mirror of
https://github.com/yattee/yattee.git
synced 2026-10-23 13:12:53 +00:00
6bf3942529e22eeb584e3ac15cc97813e2a860b3
Creating a playlist while an Invidious account was the selected context wrote it to the device. No request left the app, the row never appeared in the account's list, and the form had come up without its visibility picker — the two symptoms of the same thing: the sheet took the local branch. The destination was decided correctly and then read wrongly. The button resolved the account and put it in a companion `@State`, and the sheet's content closure — created by an earlier body evaluation — read that property as it stood *then*, which was nil. Measured on device: the create resolved the account and validity fine, and one millisecond later the sheet rendered the local form while every live value around it still named the account. Whether the stale read is corrected depends on whether anything re-renders the view before the form is saved, which is why the same steps against Piped had landed on the server. The destination now travels with the presentation as `PlaylistCreationTarget`, so the sheet is handed the account rather than looking one up. One resolver answers for both the create affordances and the row menus, and it is where the rule lives: a context reading an account's data creates on that account or creates nothing at all — a toolbar item can outlive the condition that put it there, and a write with nowhere to go is not a write to somewhere else. A context that fell back to local reads is the one case that does create locally, and it is honest: those are the rows on screen, with the banner above them saying why. Two more from the same pass: - Subscriptions stopped giving two answers at once. Under a fallback the local feed asks for a Yattee Server nobody has configured, so "Add a subscriptions account in Settings" was stacking under a banner saying this account needs signing in again. The banner names the cause, so the feed error stands down while it is up. - The playlists banner no longer lands on the search field. A navigation bar carrying a search field keeps its full height over content that cannot scroll, and the empty, loading and error states could not — they scroll now, which also gives pull to refresh somewhere to live.
Yattee 2 is in the works! A new version of the app is being built with a refreshed experience. It pairs with the new Yattee Server — a self-hosted backend powered by yt-dlp that supports 1000+ sites. Join the TestFlight beta to try early builds, and check the new documentation site at docs.yattee.stream for guides, roadmap and changelog.
Features
- Native user interface built with SwiftUI with customization settings
- Player queue and history
- Player component with custom controls, gestures and support for 4K playback
- Fullscreen, Picture in Picture and background audio playback
- SponsorBlock, configurable categories to skip
License
Yattee and its components is shared on AGPL v3 license.
Languages
Swift
96.9%
Ruby
2.7%
C
0.3%
