Parent directory

AGENTS.md

4934 bytes

ytrssil iOS app

Project

This is a SwiftUI client for the self-hosted ytrssil service.

  • Swift package: Package.swift
  • Deployment targets: iOS 26 and macOS 26
  • App entry point: Sources/ytrssil/ytrssilApp.swift
  • Main tabs: Feed, History, Channels, Settings
  • Build and install: xtool dev

Run xtool dev after app changes. It builds and installs to the connected device. Do not run production verification or add automated tests unless requested.

Files

  • ContentView.swift: configuration state and tab layout.
  • SettingsView.swift: server URL and API token form.
  • SettingsStore.swift: server URL persistence in UserDefaults; token persistence in Keychain.
  • ServerConfiguration.swift: HTTPS-only server URL validation and endpoint URL creation.
  • KeychainStore.swift: Keychain token storage.
  • APIClient.swift: authenticated JSON transport plus video and channel response models.
  • FeedView.swift: unwatched feed, local search, server fetch, custom-video entry, shared video card, thumbnails, progress editing, downloads, and external video opening.
  • HistoryView.swift: paged watched history, local search, and shared video cards.
  • ChannelsView.swift: subscribed channel list, channel subscription, unsubscribe confirmation, Shorts preference, and external channel opening.

Service contract

Use the deployed HTTPS service only. Do not add HTTP exceptions, local-server setup, test databases, or seed data.

Every API request must set Authorization to the exact configured token value. Do not use a Bearer prefix or send the token in a query parameter.

Current app routes:

  • POST /api/fetch
  • POST /api/videos with {"video_id":"YouTube URL or ID"}
  • GET /api/videos/new
  • GET /api/videos/watched?page=N
  • GET /api/videos/:video_id
  • POST /api/videos/:video_id/watch
  • POST /api/videos/:video_id/unwatch
  • POST /api/videos/:video_id/progress with {"progress":"mm:ss"}
  • POST /api/videos/:video_id/download with {"format":720}
  • GET /api/videos/:video_id/file
  • GET /api/channels
  • POST /api/channels/subscribe with {"channel_id":"YouTube channel ID, handle, or URL"}
  • POST /api/channels/:channel_id/unsubscribe
  • POST /api/channels/:channel_id/shorts?enable=true|false

The progress endpoint accepts Go duration, mm:ss, and hh:mm:ss values. It returns {"video": {...}}.

Download formats are 480, 720, 1080, 1440, and 2160. Start a download with the JSON endpoint, then poll only GET /api/videos/:video_id while that download is pending or downloading. Download completed files through the authenticated file route and export them with the system share UI. Do not reload or poll the whole feed for download status.

Product scope

Keep the app small. It supports:

  • server setup and token storage
  • unwatched feed and paged watched history
  • feed and history search by title or channel name
  • refresh and server-side fetch
  • custom-video entry from a YouTube ID or URL
  • channel subscription management and Shorts preferences
  • watched and unwatched state changes
  • saved watch-progress editing
  • server downloads and export to Files through the system share UI
  • opening videos and channels externally in YouTube or Safari

Do not add in-app playback, local service setup, downloads playback, channels beyond the subscribed-channel list, Shorts-specific browsing, custom-video libraries, service workers, cookie-auth pages, browser animation code, or automated tests unless requested.

UI

Use SwiftUI and the iOS 26 Liquid Glass system. Read .agents/skills/liquid-glass/SKILL.md before Liquid Glass UI changes.

  • Use native tabs, navigation, toolbars, forms, lists, sheets, alerts, confirmation dialogs, and search.
  • Search is a bottom tab-bar action. It opens the focused local search field for the current Feed or History list and replaces its toolbar controls. Settings is available from the top toolbar. Feed has no navigation title.
  • Wrap multiple custom glass effects in GlassEffectContainer.
  • Apply custom glass effects after layout modifiers.
  • Keep tint subtle.
  • Video cards use one static glass surface. Use bordered icon controls inside cards; do not use .glass button styling inside cards.
  • Do not add visible button text when a clear icon and accessibility label are sufficient.
  • Video thumbnails use YouTube hqdefault.jpg, center-cropped to 16:9.
  • Render saved watch progress as a six-point dark-red bar at the thumbnail bottom.
  • Render video duration as a small thumbnail overlay at bottom-right.
  • Keep channel name and relative publish time on one line, with time right aligned.
  • Show Shorts and LIVE status without making the card busy.
  • Progress editing uses a wheel-picker sheet. It supports hours, minutes, and seconds, then sends the selected value in a service-supported progress format.
  • Require confirmation before unsubscribe.
  • Never play downloaded video in the app.