Skip to content

Reader: move the sheets, interests picker and Reader tab shell to Compose - #23466

Open
nbradbury wants to merge 11 commits into
trunkfrom
reader/sheets-shell-compose
Open

nbradbury wants to merge 11 commits into
trunkfrom
reader/sheets-shell-compose

Conversation

@nbradbury

@nbradbury nbradbury commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

TL;DR

This is item 3 in the Reader → Compose plan: the Reader's bottom sheets, interests picker, Discover tabs and the Reader tab shell are now Compose.

Description

Details
  • Filter sheet: SubfilterBottomSheetFragment hosts a SubfilterSheet composable; the one-page ViewPager, SubfilterPageFragment, adapter, 7 view holders and 5 layouts are deleted. Site rows reuse ReaderSiteRow.
  • SubFilterViewModel: drops the sheet-only title visibility state and trackOnPageSelected, which never fired.
  • Small sheets: login-required, author profile and comment notifications are Compose inside the same BottomSheetDialogFragments, so callers don't change.
  • Interests picker: ReaderInterestsFragment is a Compose screen with M3 filter chips and a Compose snackbar; it still serves both the Discover overlay and ReaderInterestsActivity.
  • NoSiteToReblogActivity: setContent with an M3 top bar.
  • Shell: ReaderFragment's root is a Compose view. Feeds are key(slug) { AndroidFragment(...) }, the interests overlay is another AndroidFragment, and the AppBarLayout is replaced by ReaderShellLayout with a nested-scroll connection for hide-on-scroll. The bar lifts from the active list's real scroll position (ReaderScrollingFeed) and doesn't hide when the list can't scroll. The SubFilterViewModel owner is now the feed fragment in childFragmentManager rather than findFragmentById(R.id.container).
  • Discover tabs: PrimaryScrollableTabRow (labels no longer wrap mid-word at large font sizes) + HorizontalPager of AndroidFragment pages. A tab's list is created only once it's shown, as ViewPager2 did, and AndroidFragment's maxLifecycle keeps only the visible tab resumed.
  • Tab switches: WPMainActivity detaches the Reader for other tabs, which would dispose the composition and with it the AndroidFragment feeds. RetainedComposeView ties the composition to the fragment instead, so feeds and scroll positions survive, as the old child fragments did.
  • WPMainActivity's double-measure workaround is extracted to MeasureOnLayoutComposeView, shared by the shell and the post list.
  • ReaderTracker.trackTagLoaded moves from newInstanceForTag to ReaderPostListFragment.onCreate (fresh start only), since AndroidFragment has no factory call.
  • About 30 orphaned styles, dimens, colours and drawables are deleted.
  • Nested scroll interop: AndroidFragment's container has nested scrolling off, so Compose dropped the lists' scrolling; Fragment.enableNestedScrollInterop() turns it on.
  • Behaviour changes: filter-sheet site icons are rounded squares (matching search and Manage subscriptions); Discover tabs sit together at the start of the row rather than spreading across it.

Testing instructions

  1. Reader: switch feeds, swipe the Discover tabs, scroll, switch to Notifications and back, reselect Reader
  • The bar hides and returns on scroll, the list keeps its place across the tab switch, reselect scrolls to top
  1. Subscriptions → blog/tag chip → pick, Manage
  • Manage opens subscriptions
  1. Your tags → tags chip → Manage → + (opens "Follow tags"), toggle a few interests, tap Done
  • Chips toggle, Done enables once one is picked and shows a spinner while saving

…pose

The filter, login-required, author-profile and comment-notification sheets,
the interests picker and NoSiteToReblogActivity now render in Compose.
ReaderFragment and the Discover tabs host their feeds with AndroidFragment,
and the top bar hides on scroll through a nested-scroll connection instead
of AppBarLayout.
…compose

# Conflicts:
#	docs/USER-FACING-CHANGES.md
@dangermattic

dangermattic commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator
2 Warnings
⚠️ View files have been modified, but no screenshot or video is included in the pull request. Consider adding some for clarity.
⚠️ This PR is larger than 300 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.

Generated by 🚫 Danger

@wpmobilebot

wpmobilebot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

App Icon📲 You can test the changes from this Pull Request in Jetpack Android by scanning the QR code below to install the corresponding build.

App NameJetpack Android
Build TypeDebug
Versionpr23466-0d292fa
Build Number1498
Application IDcom.jetpack.android.prealpha
Commit0d292fa
Installation URL53r2gk11llfbg
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot

wpmobilebot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

App Icon📲 You can test the changes from this Pull Request in WordPress Android by scanning the QR code below to install the corresponding build.

App NameWordPress Android
Build TypeDebug
Versionpr23466-0d292fa
Build Number1498
Application IDorg.wordpress.android.prealpha
Commit0d292fa
Installation URL46bkcu2qoake0
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot

wpmobilebot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

🤖 Build Failure Analysis

This build has failures. Claude has analyzed them - check the build annotations for details.

Compose only forwards a hosted view's nested scrolling when that view has
nested scrolling enabled, and AndroidFragment's container doesn't, so the
Reader's top bar never hid as its lists scrolled.
…compose

# Conflicts:
#	docs/USER-FACING-CHANGES.md
…sizes

The fixed tab row split "Recommended" across two lines on a Pixel 10a with a
large font. A scrollable row widens the tabs to fit their labels instead.
ReaderTagsFeedFragment.newInstance has no callers, ReaderPostListFragment no
longer needs ViewPagerFragment's view-id swapping since no host listens for
it, and ReaderFragment's view model is always set in onCreate.
Detaching the Reader for another bottom-nav tab disposed its composition, so
AndroidFragment removed the feed fragments and rebuilt them on return. The
shell and Discover now keep their composition for the fragment's lifetime.

Discover creates a tab's list only once it's shown and caps offscreen pages
with AndroidFragment's maxLifecycle. The top bar lifts from the active list's
real scroll position and stays put when the list can't scroll, and the
interests picker shows its spinner while saving.
Switching from Discover to another feed crashed: the composition was disposed
on the fragment's ON_DESTROY, which comes after its children are destroyed,
so AndroidFragment tried to save a fragment that was no longer added. It's
now disposed when the view is destroyed by a removal, or when the activity
is destroyed, both of which come first.
@codecov

codecov Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 7.69231% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 39.31%. Comparing base (2bad4a7) to head (0d292fa).

Files with missing lines Patch % Lines
...dpress/android/ui/reader/NoSiteToReblogActivity.kt 0.00% 36 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk   #23466      +/-   ##
==========================================
- Coverage   39.33%   39.31%   -0.02%     
==========================================
  Files        2316     2317       +1     
  Lines      130396   130430      +34     
  Branches    18564    18567       +3     
==========================================
- Hits        51287    51284       -3     
- Misses      74804    74841      +37     
  Partials     4305     4305              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nbradbury
nbradbury marked this pull request as ready for review October 30, 2026 18:57
@nbradbury
nbradbury requested a review from adalpari October 30, 2026 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants