Skip to content

Complete Android download queue management and offline polish #53

Open

Description

@altaywtf

Parent

#52

Status

Shipped in #312. Open only for the live signed-in proof below; the mobile app signs in only through the Auth Tab password form, so it needs one human devs-auto sign-in (same blocker as #107).

What this delivers

The lean mobile-v1 download path from #28 gains the queue-management and lifecycle polish intentionally deferred from launch: bounded concurrency, understandable queued/running/failed state, bulk cleanup, and completion behavior users can trust.

Scope

  • Configurable concurrent-download limit (1–4, default 3, as on iOS main) with a visible queue.
  • Queued, running, paused/retryable, failed, complete, and removed states with deterministic recovery.
  • Numeric progress where the platform source provides a trustworthy denominator.
  • Multi-select removal of local copies without deleting remote originals unless a separate confirmed action is chosen.
  • Completion/failure notifications that deep-link to the local item and respect notification permission state.
  • Storage-pressure and unavailable-local-file recovery.
  • Offline playback resumes from and syncs start_from (iOS main OfflineVideoPlaybackPositionSync).
  • HLS downloads skip subtitles for hide_subtitles accounts, and the confirmed setting is stored with the download so a cold offline start hides the picker.

Acceptance criteria

Verification

  • State-machine tests with controlled download progress and process restoration.
  • Emulator/device recording covering queueing, retry, completion, bulk cleanup, airplane mode, and storage failure.
  • ./gradlew verify and mobile debug assemble green.
  • Live devs-auto lane: airplane-mode resume and start_from readback, a notification tap while signed in, missing-copy recovery, and queue order across a real process kill.

Boundaries

  • Post-v1; does not gate Epic: native Android rewrite #14.
  • No public-link or remote-trash behavior.
  • Do not persist token-bearing download URLs in logs, notifications, or durable queue metadata.

Activity

  1. altaywtf commented on Sep 30, 2026

    @altaywtf
    MemberAuthor

    Audit follow-ups for this issue (UX audit in #14, 2026-09-30):

    • Offline playback ignores start_from (mobile/downloads/OfflinePlaybackRepository.kt:35,43); iOS main resumes and syncs offline positions (OfflineVideoPlaybackPositionSync.swift).
    • iOS main has a download concurrency setting (1–4, default 3), bulk local delete and a completion notification; Android runs one download at a time. No reference has true pause.
    • HLS downloads still fetch every subtitle when the account has hide_subtitles on (found in fix(playback): pick the server's default subtitle and hide subtitles entirely with hide_subtitles #261).
  2. altaywtf commented on Sep 30, 2026

    @altaywtf
    MemberAuthor

    One more from #261's review: on a cold offline start, settings can't load, so a hide_subtitles account still sees the Captions picker for offline playback. Fix alongside the HLS-download subtitle item above (e.g. cache the confirmed hide_subtitles with the download).

  3. altaywtf commented on Oct 4, 2026

    @altaywtf
    MemberAuthor

    Shipped in #312: a visible queue with a 1–4 concurrency setting (default 3), queued, downloading, paused, failed, complete, missing and deleting states that recover after restart, multi-select local removal that never touches put.io originals, permission-aware notifications, low-storage pause, offline `start_from` resume and sync (iOS rules), and `hide_subtitles` for HLS downloads.

    • Proof: `./gradlew verify` and the four debug assemblies, 17 negative controls (real Media3 manager, index and cache in the engine tests), and an on-device recording of the queue, a forced low-storage pause, notifications with the permission denied and granted, and bulk delete.
    • Review fixes: the sync never writes an older position over the player's newer one, and an unreadable index keeps unreadable rows and recovers lost downloads as rows; bytes leave only through a confirmed delete.
    • Open, so this stays open: the live `devs-auto` lane (airplane-mode resume and `start_from` readback, a notification tap while signed in, missing-copy recovery, queue order across a real process kill). The mobile app signs in only through the Auth Tab password form, so it needs one human sign-in.

    Written by an agent (Claude Code, Opus 5.5)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions