Refactor/layering - #46
Open
poluruprvn wants to merge 8 commits into
Open
poluruprvn wants to merge 8 commits into
poluruprvn wants to merge 8 commits into
Conversation
The player's "Checking stream 1 of N…" gate counts up to QuickPlayRules .maxAttempts, but the slider that set it was dropped when the Quick Play page was simplified. The pref survived upgrades and is per-device, so users saw different counts on different installs (a desktop carrying an old 10 next to a fresh Apple TV on the 5 default) with no way to change either. Adds a "Streams to try" dropdown (1-10) inside the Movies/Series tabs, since the budget is per-content. It reads and writes the effective value the players compute -- `tryNext ? maxAttempts : 1` -- so a legacy profile with failover off shows 1 rather than a stale maxAttempts nothing honors, and picking 1 disarms tryNextOnFailure instead of leaving a count the ladder would ignore. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…okmark A pinned-source launch commits its startup candidate ~40ms into decode and seeks to the stored position 2ms later; on a fresh debrid stream mpv can answer that seek by restarting at 0, and the exit save then filed ~2s over the real bookmark (observed on-device: 2169ms over 661786ms) — locally and, via the scrobble stops, on every connected tracker. ResumeWriteGuard (new, unit-tested) arms at every resume seek and blocks shallow writes until the seek lands, the viewer seeks, or a 30s settle window elapses. Blocked writes persist the promised target instead of being dropped, so speed/aspect changes survive and trackers scrobble the position the resume promised. Startup seeks are verified and re-issued once if they did not land; source switches, the renderer fallback, and the manual source sheet carry the held target instead of the restart artifact. Near-finished targets (>=80% of duration) never arm, so a held position can never fabricate a watched mark. Every content open invalidates the outgoing media's protection at the _openMedia choke point. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The activity's anti-yank guard can drop the resume seek (late-resolving duration) and a stream can clamp one away — either way progress reports then carry the shallow live position and overwrite the very bookmark the resume promised, locally and on every tracker, because one positionMs feeds both. The hold lives in the activity itself, armed with the exact target the READY handler chose (including the anti-yank drop branch, capped to near-start), so there is no Dart-side re-derivation to drift out of sync. While armed, sendProgress substitutes the target for the live position; completion stays on the raw position so a held target can never fabricate a watched mark, and near-finished targets (>=80%) never arm. Releases on landing, any viewer seek (controls, skip, a >3s backward discontinuity for remote seeks — the floor keeps the subtitle-offset self-seek from releasing), item change, the Stremio TV payload swap, or a 30s settle window. Source switches and the manual-candidate rollback snapshot carry the held target instead of the restart artifact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
"Playback stops instead of falling back" overstated it: probeAttemptCount's pack-top safety still probes the best single episode when a season pack was ranked first, even at 1 stream. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the PikPak singleton and ad-hoc HTTP calls with a composition root: one injected HTTP gateway (timeouts, retries, typed decoding) and an injected PikPak client behind every call. PikPak returns typed files and tasks instead of Map<String, dynamic>, and the two token-refresh paths collapse into one. Debrid providers resolve through a registry rather than broadcasting questions to every provider, and the browser logic each cloud provider had rewritten now lives in one place. Source files are grouped by feature and named for their role; PlaylistEntry moves into the domain layer; the deprecated screens and home sections are deleted.
…sion The Map -> typed-model conversion left call sites reading kind/phase/size as the wire values they used to be. All of them compile, the analyzer reports eight as info, and one is invisible to it (String == String). Each lands in an existing swallowing catch, so the symptom was a reassuring wrong answer rather than an error: - tv_service indexed a PikPakFile with file['mime_type'], throwing into _findVideoInFolder's catch — every pack resolved as "no source" - phase == 'PHASE_TYPE_COMPLETE' was always false, so "Play folder" and "Add folder to playlist" always reported an empty folder - kind as String? and size as String? threw TypeError, killing search - kind == 'drive#folder' never recursed, flattening playlist folder trees - select-all took virtual season rows, then deleted their synthetic ids PikPakFile already had isFolder/isFile/isVirtual/isReady/isVideo and used them correctly elsewhere; these sites now do too. Tighten the parsers so this class cannot come back by hand: fromJson takes Map rather than dynamic, which makes the shape the compiler's obligation and deletes the `json as Map` runtime stand-in; a malformed list entry is filtered with whereType instead of throwing away the whole listing; and a missing captcha token raises PikPakUnexpectedResponse rather than a TypeError that escaped the sealed PikPakApiFailure hierarchy. A failed token refresh no longer clears the session. refreshAccessToken returns false for recoverable reasons too — the 60s re-auth cooldown, a network blip, a profile-scope StateError — and expire() cleared the stored email, password, tokens, device id and restricted-folder pin, and set pikpak_enabled false. refreshAccessToken already logs out in the one unrecoverable branch, so expire() leaves the interface entirely. Also restores guards the refactor dropped (empty-list batchTrash/Delete, the fileId null check in magnet_link_handler), stops destinationId falling back to a task id across two id spaces, lets a failed download phase escape its poll loop instead of waiting out the 5-minute timeout, fires onProgress at 0%, keeps unknown-size videos out of the 100 MB floor, and makes the two readings of Real-Debrid's `selected` agree. unrelated_type_equality_checks is now an error and packages/** is excluded from analysis (it contributed 917 phantom errors). A guard test covers the toString() and as-String forms the analyzer cannot see. Doc fixes: the four blocks claiming the new layers are adopted now say what is still live, the fabricated "90% local finished cutoff" is gone (it is user-configurable, default 80, clamped 50-95), CODEMAP points at files that exist, and test_baseline.py stops writing a wrong path into its own header. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
flutter analyze only flags unused *private* members, so orphaned public widgets and whole files accumulate invisibly. dart_code_linter walks the import graph from lib/ and reports both; dev/tool/dead_code.sh runs it. Adding the dep re-resolves matcher/meta/test_api in pubspec.lock.
Found by dev/tool/dead_code.sh: no file in lib/, test/ or dev/ references any of these, and none is a `part`. ~11.9k lines. Left in place pending a look: features/pikpak/view_model.dart (only its test keeps it alive) and app/cloud_sources.dart.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.