🚀 ytdl-material 1.1.1
This patch release adds automatic subscription playlists, makes playlist and subscription archive downloads ask before they start and cancellable once they have, fixes Add to playlist opening empty for audio files, and makes cancelling a download actually stop the downloader instead of only reporting that it did.
Nothing here changes an existing route, response shape or config key. Upgrading needs no action.
✨ Features
- Automatic subscription playlists. Opt in per subscription, at creation or from its edit dialog, and a playlist named after the channel is created — or backfilled from what you already have — and every completed download is appended to it. Appends are idempotent and concurrent completions are serialized, so a burst of finishes cannot double-add or interleave; stale entries are pruned on synchronization. Unsubscribing cleans up the playlist it manages while detaching anything you added yourself rather than deleting it. The playlist editor also gained the full library rather than a page of it, filtering by subscription source, Select all files and Clear selection. Closes #399. #406
- Playlist cards show how many files they hold. A card gave no sense of its size, so the only way to find out was to open it and count. The count sits under the title as subtext — items rather than videos, since a playlist holds audio just as readily and carries nothing that says which. Small cards have no room for a second line and still show the title alone. Closes #400. #402
🛠️ Fixes
- Archive downloads ask first, and can be cancelled. Building a zip of a playlist or a subscription started the moment you clicked, with no indication of how big it would be and no way to stop it. There is now a confirmation dialog showing the file count and estimated uncompressed size, and a visible Cancel in place of the action while the archive is being prepared or transferred. Cancelling — or simply leaving the page — aborts the request, and the server ties archive generation to the client connection so queued work stops and partial zips are removed rather than left on disk. Closes #398. #405 #407
- Cancelling a download now actually kills the process. The kill helper was declared async but awaited nothing, and
tree-killonly delivers signals from inside its callback — so it returned while the child was still running, not merely unreaped but not yet signalled. Callers marked the download cancelled and dropped the reference while yt-dlp was still writing, leaving zombies behind. Both callers now await a bounded wait that also handles a child which had already exited, a subscription whose process came back from a remote database as a plain{pid}object, an undefined pid between spawn and a failed spawn, andEPERMfrom the signal itself. #396 - Add to playlist no longer opens empty. The menu offered only playlists whose type matched the file's, but a playlist's type is never written — nothing has ever set one — so the check reduced to "the file is strictly video". Audio files got an empty menu every time, as did any older record stored without an
isAudioat all, and the trigger stayed enabled because it only checked whether any playlists existed rather than whether any survived the filter. Nothing else in the app draws that distinction: the create and edit dialog has always picked from every file, and the player types each item as it plays it. The filter and the phantomtypefield are both gone. Closes #401. #403 - The player's action bar icons have names. Download, share, info and the chat toggle had no tooltip and no
aria-label, which says nothing on hover and nothing to a screen reader. The playlist download was a floppy disk giving no hint whether it took the current file or everything — it is afolder_zipnow and says so. Idle toggles are no longer dimmed to 0.6 opacity, so every icon in the row rests at the same colour, and an engaged one shows a neutral chip behind it that reads correctly in all three themes. The toggles also gainedaria-pressed, which is what the dimming was standing in for and never conveyed. #403
📦 Dependencies
- Two packages were imported but never declared.
@discordjs/restis required by the notification path and arrived only as a transitive of@discordjs/core;js-yamllikewise viamocha. Either supplier dropping or bumping them would have broken notifications at require time, in a release that touched nothing related. Both are now declared. #408 mochano longer ships to production. It sat independenciesdespite being invoked only by the test script, sonpm ci --omit=devinstalled the whole test runner into the image — 291 packages before, 279 after. Six further packages (async,config,express-session,lowdb,md5,passport-http) were declared but referenced nowhere, some since 2020, and are gone too. #409 #411- Refreshed both lockfiles so installed versions match their declared ranges, which had been failing the dependency check on main since #407:
@angular/cli,@angular/buildand@angular-devkit/coreto 22.1.6,axiosto 1.20.0. Also bumpedgithub/codeql-actionand movedeslintto 10.9.0. #404 #410 - Removed the abandoned electron scaffolding —
main.js, its npm script and twoangular.jsontargets. The dependency went in 2023 and the entry point was never wired up, so it could not have run even then. #413 - Added
dev/deps/check-declared.mjs, which resolves every import in both trees back to a package name and fails on anypackage.jsondoes not declare — the guard for the class of bug above. Not part of CI; see DEVELOPMENT.md. #412
Full Changelog: v1.1.0...v1.1.1
Contributors
- @jamesbiederbeck — first contribution, for spotting and fixing the zombie processes left behind by a cancelled download
- @voc0der