Skip to content

Apply the Reader flag when it's fetched, not on the next launch - #26303

Draft
jkmassel wants to merge 2 commits into
jkmassel/ipad-tab-bar-follows-app-ui-typefrom
jkmassel/reader-flag-applies-without-relaunch
Draft

jkmassel wants to merge 2 commits into
jkmassel/ipad-tab-bar-follows-app-ui-typefrom
jkmassel/reader-flag-applies-without-relaunch

Conversation

@jkmassel

@jkmassel jkmassel commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the WordPress app ignoring a fetched readerInWordPressApp flag until the next launch. A WordPress.com account's first session on a fresh install got the posters instead of the live Reader, and needed a relaunch to get it. Stacked on #26302.

Root Cause

JetpackFeaturesRemovalCoordinator.isReaderInWordPressAppEnabled was a static var read once per launch, before the launch fetch had finished.

On the simulator, the log showed this order on a fresh install:

Step Reader flag
Fetch at launch, signed out false
Sign in to WordPress.com, which fetches again true (the flag targets the account)
UI shown afterwards Still static screens, because the flag had already been read

RootViewCoordinator also only watched for account changes if the flag was on at launch. So a flag that arrived later never took effect in that session.

The value was frozen on purpose: it also decides the scope of the Notifications lists, and reading it live could leave a list and the root UI disagreeing. This PR keeps that guarantee by changing the flag and the UI type at the same moment.

Changes

  • WordPressAppDelegate.updateFeatureFlags posts RemoteFeatureFlagStore.didUpdateNotification on the main queue after each fetch. It only posts a notification: the first fetch can finish before any scene connects, so it must not touch the UI. An earlier version of this branch called RootViewCoordinator.shared directly and crashed at launch with windowManager accessed before any scene connected.
  • RootViewCoordinator.remoteFeatureFlagsDidUpdate() reads the flag again. If it changed, it updates isReaderInWordPressAppEnabled and the app UI type together.
  • The account-change observer is always registered, but only acts while the flag is on. A launch with the flag off keeps its UI type until the next reload, as before (testSignInKeepsLaunchUITypeUntilReloadWhenFlagIsOff).
  • Jetpack and the Reader app are unchanged: the flag only applies to the WordPress app.

Test plan

  • New tests in RootViewCoordinatorTests:
    • the flag turning on, and turning off, after launch rebuilds the iPhone UI, and the Notifications scope follows
    • an unchanged flag leaves the UI alone
    • a flag fetched on the sign-in screen applies to the next sign-in, delivered through the notification
    • a flag fetched after a logout doesn't replace the sign-in UI
    • Jetpack is unaffected
  • The logout test fails without the sign-in check, every time across three retries: Executed 37 tests, with 3 failures. The other new tests can't run on Keep the iPad Reader and Notifications behind the Jetpack features removal #26302's code, because remoteFeatureFlagsDidUpdate() doesn't exist there.
  • RootViewCoordinatorTests, NotificationsViewControllerTests and MovedToJetpackViewModelTests pass: Executed 53 tests, with 0 failures, and Test run with 2 tests in 1 suite passed. RootViewCoordinatorTests alone also passes after the sign-in check was added: Executed 35 tests, with 0 failures.
  • iPhone 18 Pro iOS 27.0 simulator, fresh install of the WordPress app, signed in to WordPress.com: the first session switches to the live Reader with the Notifications poster, no relaunch needed. Before this change, the same steps gave static screens until a relaunch.
  • iPad Pro 13-inch (M5) simulator, same steps: the first session switches to the live Reader in the narrow-window tab bar.
  • Changing the flag mid-session, using a temporary debug override that posts the same notification:
    • iPad: switches in place (same tab bar) to the Reader poster and back.
    • iPhone: the UI is rebuilt into static screens and back.
    • No assertions or fatal errors in the log.

Reader menu in the WordPress app on the first session after a fresh install

Not tried: a physical device, and a real server-side change to the flag in the middle of a session (simulated with the override instead).

Related issues

JetpackFeaturesRemovalCoordinator.isReaderInWordPressAppEnabled was read
once per launch, before the launch fetch finished. A fresh install has no
cached value, and the flag can target an account, so a WordPress.com
account's first session in the WordPress app ran as staticScreens even after
the fetch returned the flag. It took a relaunch to get the live Reader.

After each fetch, RootViewCoordinator reads the flag again. When it changed,
it updates the flag and the app UI type together, so Notifications lists
created afterwards get the matching scope. The iPad split view applies the
type in place; the other presenters are rebuilt through reloadUIIfNeeded.
The account-change observer is now registered whatever the flag's launch
value, and acts only while the flag is on, so a launch with the flag off
keeps its UI type until the next reload, as before.
After a logout, presentedAppUIType still holds the old type, so a fetch that
changed the Reader flag reloaded the UI and WindowManager.showUI replaced the
sign-in flow. The next showAppUI uses the new type anyway.
@jkmassel jkmassel added this to the 27.5 milestone Oct 29, 2026
@jkmassel jkmassel self-assigned this Oct 29, 2026
@dangermattic

Copy link
Copy Markdown
Collaborator
1 Message
📖 This PR is still a Draft: some checks will be skipped.

Generated by 🚫 Danger

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants