Skip to content

refactor(subscriptions): restructure the screen, share its components, and adopt expressive controls - #1035

Merged
A-EDev merged 16 commits into
mainfrom
refactor/subscriptions-screen
Sep 7, 2026
Merged

A-EDev merged 16 commits into
mainfrom
refactor/subscriptions-screen

Conversation

@A-EDev

@A-EDev A-EDev commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Summary

Splits the 1,309-line subscriptions screen into nine focused files and moves its shared pieces out: one subscribe button now backs the channel page, the player and the manager, and one expressive pull-to-refresh backs every refreshing surface. Adopts M3 Expressive controls on the way, fixes the missing refresh progress bar, and adds channel groups to the channel page.

Related issue

Closes #995
Closes #982

Change type

  • Bug fix
  • Feature
  • Refactor or maintenance
  • Build, packaging, or CI
  • Documentation

Validation

  • ./gradlew :app:assembleGithubDebug
  • ./gradlew :app:testGithubDebugUnitTest
  • I ran any additional flavor-specific build or test tasks affected by this change.
  • I manually tested the affected behavior on an Android device or emulator.

Also run and passing: ./gradlew spotlessCheck, :app:compileGithubDebugKotlin, :app:compileFossDebugKotlin.

Test device and Android version: Xiaomi POCO X6 Pro, HyperOS 3.0.9.0, Android 16

Two crashes were found on device during testing and are fixed here: ButtonGroup throwing from its measure policy under a tight width constraint, and the groups dialog painting rows over the dialog container. The performance changes below are structural — they have not been measured with a profiler.

Screenshots or recordings

Risk and compatibility

Fixes

  • [Bug]: Subscription feed refresh progress bar isn't showing #995 — the refresh progress bar was gated on isLoading, which the launch refresh deliberately leaves false so the pull indicator does not spin on every start. The channel counts were always published, so the bar now follows those instead. Regression from 2.2.0.
  • [Feature]: Being able to add to channel groups directly from the channel tab #982 — groups can be added and removed from the channel page via the subscribe menu, reusing the existing SaveToCollectionSheet.
  • Subscription avatars went through a raw AsyncImage, skipping ThumbnailUrlResolver and the placeholder fallback that every other avatar in the app uses.
  • An always-true || true guard, an unreachable selected-avatar branch holding hardcoded Color.Black/Color.White, and context.getString inside composition.
  • Captured logs were flooded by BLASTBufferQueue/HWUI frame spam; those tags are now silenced through logcat's filterspec, and the per-channel failure reason is recorded when the fetch fails rather than scraped back out of logcat.

Behaviour changes worth knowing about

  • SubscriptionsViewModel is now activity-scoped on phone (sharedSubscriptionsViewModel()), matching what the TV shell already did. A tab visit no longer builds a fresh instance whose ensureStarted() restarts five collectors and another feed refresh, and feed and scroll state now survive tab switches.

  • Two refresh timers are now gated. The 60 s relative-time tick suspends while nothing observes the feed state, and the 3-minute stale poll runs only while RESUMED. The tick re-maps, filters and sorts the whole feed, so it was not a cheap clock update.

  • The subscribe button is a split button when subscribed — the leading half toggles notifications, the trailing half opens the menu. It replaces three implementations, two of which were both named SubscribeButton. Shorts and TV keep their own.

  • New preference show_channel_group_badges, off by default. With it off the group table is never observed at all.

  • SubscriptionGroup moved from ui/screens/subscriptions/ to data/model/, so the channel page can use it without importing another feature's screen package.

  • Two new fields on existing data classes (failedChannelReasons on the refresh progress and UI state). No entity or schema change.

  • 4 new strings in values/strings.xml. Other locales are left to Weblate.

  • The change does not introduce secrets, private data, or unexpected telemetry.

  • New user-facing text uses Android string resources.

  • Dependency and lockfile changes are intentional and limited to this PR.

  • Room schema changes include the required version bump and migration, or this PR does not change the Room schema.

  • Breaking changes and upgrade steps are clearly documented.

Copilot AI lite review requested due to automatic review settings September 7, 2026 18:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added the ui Compose UI, theming, or Material 3 surfaces label Sep 7, 2026
@A-EDev
A-EDev merged commit 0c1d506 into main Sep 7, 2026
5 checks passed
@A-EDev A-EDev added the merged Pull request verified, tested and merged label Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged Pull request verified, tested and merged ui Compose UI, theming, or Material 3 surfaces

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Subscription feed refresh progress bar isn't showing [Feature]: Being able to add to channel groups directly from the channel tab

2 participants