Files
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

1 line
379 B
JSON

{"default":{"identifier":"default","description":"Capability for the main window and the menu bar panel","local":true,"windows":["main","tray"],"permissions":["core:default","opener:default","dialog:default","core:window:allow-start-dragging","core:window:allow-is-fullscreen","notification:default","core:event:allow-emit-to","core:event:allow-emit","core:event:allow-listen"]}}