Skip to content

Complete Android download queue management and offline polish #53

Open

Description

@altaywtf

Parent

#52

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 or product-decided concurrent-download limit 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; today OfflinePlaybackRepository starts at 0).
  • Download concurrency setting (iOS main: 1–4, default 3; today 1).
  • 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

  • Queue ordering and concurrency survive process recreation.
  • Failed or interrupted downloads recover without silently losing queue state.
  • Bulk local deletion cannot delete remote originals implicitly.
  • Notification and permission-disabled states are both verified.
  • Offline playback and local-availability indicators remain correct after queue operations.

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.

Blocked by

Boundaries

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