Track downloaded streams and surface status on video detail
What is it?
- [ ] Bugfix (user facing)
- [x] Feature (user facing)
- [ ] Codebase improvement (dev facing)
- [ ] Meta improvement to the project (dev facing)
Description of the changes in your PR
- add a downloaded_streams Room table/DAO, migration v10, and generated schema JSON so NewPipe can remember which videos were downloaded (with SAF URIs, quality label, etc.)
- hook the downloader enqueue/finish paths to insert/update those rows, and add lightweight self- healing (video-open probe, downloads-screen refresh, periodic WorkManager job)
- show a “Downloaded …” chip on the video detail page; when tapped it opens a themed sheet with:
- Open file, Delete file (also unlinks), Remove link, Show in folder when the file is still present
- Remove link when the file is gone
- deleting or removing the link immediately hides the chip
Before/After Screenshots/Screen Record
- Before: no indication that the stream was already downloaded; tapping “Download” always enqueued a new mission.
- After: a “Downloaded • 720p” chip appears above the metadata; tapping it reveals the action sheet described above. (No visual regression screenshots attached.)
https://github.com/user-attachments/assets/ecb91088-d9f6-4f64-8933-9128a07c0aa6
Fixes the following issue(s)
- Fixes #7360
Relies on the following changes
- (none)
Thank you for this cool PR! I have some general comments:
- Is there a reason why you added new database tables to keep track of downloads, when the downloader already has its own tables in the database? See https://github.com/TeamNewPipe/NewPipe/blob/1164ea52f97247d968e717a6df5381d53dac68dc/app/src/main/java/us/shandian/giga/get/sqlite/FinishedMissionStore.java#L25 . This class is veeeery old and is for sure bad code, so you are free to create new DAOs, but please don't create new redundant tables ;-)
- New UI code on the refactor branch should ideally be written in Jetpack Compose instead of XML
- Could you move out the code related to this button from the VideoDetailFragment file, so it doesn't get too complicated?
Hey thank you for the encouraging feedback! I figured it was good to get a rough demo in shape before spending time on anything else.
(This pass was planned by GPT-5 Pro with limited access to the source code which is probably why I overlooked the existing table ;) I'm setting the PR to draft and will bring it back for review when I have addressed your feedback.)
Oh, I see. If you use LLMs to make contributions to open source projects, I strongly suggest making sure you only use LLMs as a companion to get some help, not to blindly generate code, as the latter just creates unneeded review work for maintainers (which would be able to use LLMs themselves if they really wanted to).
Definitely doing the best I can to get up to speed on a new codebase. I haven't done much android development in the kotlin era :)
(Meta-level perspective: deciding what problems are worth tackling, coming up with a design, implementing it, and testing all still require significant nvestment, even with help from LLMs, so I'm not sure "maintainers would just use LLMs to do it all themselves if they wanted to" entirely holds -- e.g., #7360 has been open for almost 4 years, and I think I've made decent progress with 3-4 hours of my own time investment, plus your generous feedback + advice here. For me, part of the joy of open source is letting users learn, propose, and contribute things they care about.)
That said: I don't want to waste your time if you're not interested in this contribution -- it's your project, your rules, @Stypox!
I've updated this PR to address your initial feedback, but please let me know if you'd prefer to close the PR vs continuing a review cycle.
No worries -- just wanted to make sure I'm contributing in a productive way. Really appreciate the review + comments here.
Could you add a few comments in the code explaining how the data flows from the various places? E.g. in DownloadStatusRepository, explain why the binding setup is needed, why its implementation is correct, and which parts are important to get right.
Added KDoc over observe()/withBinder() that walks through the lifetime of the service bind, the handler callback, and the teardown. The repository now always uses that helper, so there’s a single, documented spot managing the binder lifecycle.
Addressed other comments above inline.