Commit Graph
3 Commits
Author SHA1 Message Date
Vincent Rozenberg 22e31afc1d feat: remove every subscription from Settings, and reopen the last video
Remove all sits beside Import in Settings, since emptying the list is
the other half of replacing it. It asks first and counts what goes:
210 channels, 3339 videos, 50 downloaded files, in those words. Nothing
changes on YouTube, and the confirmation says so — importing or reading
the list again brings it all back.

It takes the same path an import does when nothing survives, so a video
saved on its own from the menu bar is left alone: its channel was never
a subscription, and this is about subscriptions.

The app also reopens whatever was playing when it last closed, if that
video is still in the feed and still playable — offline, one that was
streaming is not. The note is made while the player is open and dropped
when it is closed, so a restart only reopens something you were in the
middle of, never something you had deliberately finished with. Verified
both ways: quitting mid-video came back to it, closing the player first
came back to the feed.

The panel's Remove all downloads is gone; it was a misreading of the
request.
2026-09-04 02:03:46 +02:00
Vincent Rozenberg 35f14ab044 feat: fullscreen carries across videos, and stays out of the way
In fullscreen, Next now keeps you there and shows nothing but the
picture: one video after another, no arrows, no header, no counter.

Three things had to change for that. The player was keyed on the video,
so every Next rebuilt the stage — and the stage is what is fullscreen.
It now survives, resetting its own per-video state instead of being
thrown away to get it.

The cleanup that ran on every change of source called exitFullscreen
outright. It exists for the Picture-in-Picture leak, which does need
handling per video; leaving fullscreen and dropping the source belong
to leaving the player, and are now only done there.

And resolving a stream set the source to nothing first, which unmounted
the element mid-fullscreen. The outgoing video is paused in place
instead, and the source goes straight from one address to the next.

The edge arrows are gone in fullscreen. The transport bar stays — it is
playback, not navigation — and fades on its own as before.

Also: Remove all downloads in the menu bar panel, which asks in the
window rather than in a panel that closes when you look away; and the
JavaScript round-trip logging is gone now that the scrape is settled.

Verified in the running app: three videos in a row without leaving
fullscreen, chrome faded to nothing, and Remove all reaching the
window's own "Delete every download?" with 50 downloads left untouched.
2026-09-04 01:56:08 +02:00
Vincent Rozenberg 41d638b232 feat: read the subscription list off YouTube, and an app-shaped menu bar panel
Takeout is a snapshot you have to go and fetch. This reads the live list
from youtube.com/feed/channels in a browser already signed in.

It runs JavaScript in the page rather than fetching it here, because
the session cannot be borrowed: Chromium encrypts its cookie store with
a per-app Keychain key, and Arc's cookies read with Chrome's key came
back undecryptable — 1346 of 2196, the session cookies among them. The
list is also lazily loaded, so it has to be scrolled to the end, which
only the page can do. Measured against a hand-scrolled count: 208 both
ways.

The browser is brought to the front first. A background tab has its DOM
discarded, so it reports its address while having nothing on it, which
reads exactly like an empty subscription list.

The page gives handles, not channel ids. Most belong to channels already
known here and are matched by name, costing nothing; only the rest are
looked up, four at a time. That mattered more than it sounds: with the
name selector wrong every name came back empty, nothing matched, all 208
were looked up blind, and the result claimed 58 channels should be
deleted. With names read correctly it is 4 lookups and 0 deletions.
Names arriving doubled — "3D OCD 3D OCD", which reads fine and matches
nothing — are collapsed.

osascript prints a string result in source form, quoted with the
newlines escaped, so a list of rows arrived as one line that looked
like no rows at all. It is unquoted before parsing.

The menu bar item is now a window, not an NSMenu: the app's own type,
spacing and colours, hanging from the icon and closing on blur. Adding a
channel is gone from it — the sidebar already does that.

Replacing the subscription list is confirmed in the main window, never
in a panel that closes when you look away, and the confirmation counts
what would go before anything happens.

Verified end to end: 208 read, 4 looked up, 0 removed, 48 downloads
untouched.
2026-09-04 01:34:29 +02:00