Skip to content

Add GutenbergKit opt-in announcement and per-site override#22813

Draft
jkmassel wants to merge 1 commit into
trunkfrom
jkmassel/gutenbergkit-opt-in
Draft

Add GutenbergKit opt-in announcement and per-site override#22813
jkmassel wants to merge 1 commit into
trunkfrom
jkmassel/gutenbergkit-opt-in

Conversation

@jkmassel
Copy link
Copy Markdown
Contributor

@jkmassel jkmassel commented Apr 22, 2026

Adds a per-site GutenbergKit opt-in surfaced as a one-time bottom sheet on the My Site screen, with a matching toggle in Site Settings. The remote gutenberg_kit flag only gates the announcement / Settings toggle visibility — it is deliberately not part of editor routing.

Summary

  • Show / defer / activate decisions live in GutenbergKitAnnouncementController — pure logic, unit-tested via an injected java.time.Clock.
  • The per-site override is the single source of truth: presence (either direction) means the user has decided for that site; absence means we may prompt. No global opt-in flag, no separate "shown" flag.
  • Maybe later writes a per-site GUTENBERG_KIT_ANNOUNCEMENT_DEFERRED_UNTIL_<url> 7 days out instead of locking in an opt-out. Swipe / back / tap-outside is treated as an implicit Maybe later so the sheet doesn't re-prompt on every My Site resume.
  • Editor routing in GutenbergKitFeatureChecker is siteOverride ?: experimentalFlag && !disableKillSwitch. The remote gutenberg_kit feature flag is intentionally not in this expression — it only gates announcement / Settings toggle visibility. This lets us roll the announcement to a percentage of users without simultaneously flipping the default editor. When we're ready to make GutenbergKit the default for everyone, the change is a one-line edit (hard-code the fallback to true).
  • Site Settings Try the new editor toggle: visible while the remote flag is on; checked state mirrors GutenbergKitFeatureChecker.isGutenbergKitEnabled(site) so it always reflects what the editor will actually do; on Aztec-default sites the row is shown disabled with an explanatory summary so users can still discover the option without a silent bundle-flip of mobileEditor.

Changes

  • GutenbergKitAnnouncementController.kt (new): shouldShowAnnouncement(site), onActivate(site), setOverride(site, enabled), onMaybeLater(site). setOverride always clears any deferral, so "explicit decision supersedes a pending defer" lives in one place.
  • GutenbergKitFeatureChecker.kt: editor-routing resolution drops the remote flag from the OR; only siteOverride and experimentalFlag decide, with the kill switch winning over both. Field isGutenbergKitFeatureEnabled on FeatureState is kept for logging / informational purposes only.
  • MySiteViewModel.kt / MySiteFragment.kt: announcement check moved to My Site onResume(). Posts _onShowGutenbergKitAnnouncement: SingleLiveEvent<Event<SiteModel>>. Fragment observer guards with isStateSaved and an already-attached-instance check before .show().
  • GutenbergKitAnnouncementBottomSheetFragment.kt: @AndroidEntryPoint, Hilt-injected controller, takes a SiteModel via newInstance(site). Activate / Maybe later / dismiss-without-decision all route through the controller. Insets only consume Type.statusBars() so IME / gesture / bottom-bar insets still propagate. "Learn more" uses a %1$s placeholder so translators can position it anywhere in the body.
  • SiteSettingsFragment.java: new mGutenbergKitPref row. refreshGutenbergKitToggleAvailability() is called from both initPreferences() and setPreferencesFromSiteSettings(), so flipping "Use block editor as default for new posts" on the same screen re-enables the GBKit row without leaving Settings. Toggle writes go through mGutenbergKitAnnouncementController.setOverride(...).
  • AppPrefs.java: GUTENBERG_KIT_OPT_IN_SITES / OPT_OUT_SITES (deletable StringSets) and per-site GUTENBERG_KIT_ANNOUNCEMENT_DEFERRED_UNTIL_<url> longs. The previous draft's GUTENBERG_KIT_USER_OPT_IN and GUTENBERG_KIT_ANNOUNCEMENT_SHOWN undeletable flags are removed — there's no longer any state that should survive logout.
  • EditorLauncher.kt: logFeatureDisabledReason and getFeatureFlagsString updated to reflect the new resolution (mentions site override, no longer claims the remote flag enables routing).
  • EditorCapabilityResolver.kt: passes site through the GBKit gate so Theme Styles and Third-Party Blocks resolve against the same per-site view the launcher uses.
  • RELEASE-NOTES.txt: entry under 26.8.

Test plan

  • Fresh install, remote flag on, site defaults to block editor:
    • Open the app → My Site → announcement appears.
    • Tap Activate → sheet dismisses → creating a new post on that site opens GutenbergKit. Returning to My Site, the sheet does not reappear.
    • Tap Maybe later → sheet dismisses → does not reappear within the 7-day window. Verify reappearance after expiry by shortening DEFER_DURATION_MILLIS locally (or jumping the device clock).
    • Swipe down / tap outside / back-button dismiss behaves the same as Maybe later (no reappearance for 7 days).
  • Remote flag on, no per-site opt-in, no experimental flag:
    • Creating a new post opens Aztec / legacy editor, not GutenbergKit. (Verifies the remote flag no longer gates editor routing.)
  • Aztec-default site (mobileEditor == "aztec"):
    • Announcement does not appear on My Site.
    • Site Settings shows "Try the new editor" disabled, with summary including "Switch to the block editor first…".
    • Toggling Use block editor as default for new posts ON → after the settings refresh, "Try the new editor" re-enables in place without leaving the screen.
  • Site Settings Try the new editor toggle:
    • Toggle ON → that site opens GutenbergKit; other sites are unaffected.
    • Toggle OFF after opting in → that site opens Aztec.
    • After Maybe later on the sheet, toggling the Site Settings switch (either direction) clears the deferral.
  • Remote flag off:
    • Announcement does not appear.
    • "Try the new editor" row is hidden in Site Settings.
  • Configuration change: rotate the device while the sheet is open → sheet recreates without writing a deferral.
  • Unit tests: GutenbergKitAnnouncementControllerTest, GutenbergKitFeatureCheckerTest, EditorCapabilityResolverTest, MySiteViewModelTest pass.

@dangermattic
Copy link
Copy Markdown
Collaborator

1 Warning
⚠️ This PR is larger than 300 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.
1 Message
📖 This PR is still a Draft: some checks will be skipped.

Generated by 🚫 Danger

@wpmobilebot
Copy link
Copy Markdown
Contributor

wpmobilebot commented Apr 22, 2026

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
Versionpr22813-2bfdd30
Build Number1488
Application IDorg.wordpress.android.prealpha
Commit2bfdd30
Installation URL22i2ofq2bj04g
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot
Copy link
Copy Markdown
Contributor

wpmobilebot commented Apr 22, 2026

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
Versionpr22813-2bfdd30
Build Number1488
Application IDcom.jetpack.android.prealpha
Commit2bfdd30
Installation URL5upnoserlfrb0
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot
Copy link
Copy Markdown
Contributor

wpmobilebot commented Apr 22, 2026

🤖 Build Failure Analysis

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

@jkmassel jkmassel force-pushed the jkmassel/gutenbergkit-opt-in branch 3 times, most recently from 71d2a8f to 24faca7 Compare May 25, 2026 19:40
@jkmassel jkmassel changed the title Add per-site GutenbergKit opt-in and announcement bottom sheet Add GutenbergKit opt-in announcement and per-site override May 25, 2026
@jkmassel jkmassel force-pushed the jkmassel/gutenbergkit-opt-in branch from 2130282 to 046f3cd Compare May 25, 2026 19:47
@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

Codecov Report

❌ Patch coverage is 39.77273% with 53 lines in your changes missing coverage. Please review.
✅ Project coverage is 37.34%. Comparing base (96fc478) to head (2bfdd30).

Files with missing lines Patch % Lines
.../java/org/wordpress/android/ui/prefs/AppPrefs.java 0.00% 38 Missing ⚠️
...a/org/wordpress/android/ui/posts/EditorLauncher.kt 0.00% 8 Missing ⚠️
.../org/wordpress/android/ui/prefs/AppPrefsWrapper.kt 0.00% 4 Missing ⚠️
...ess/android/ui/posts/GutenbergKitFeatureChecker.kt 81.81% 1 Missing and 1 partial ⚠️
...org/wordpress/android/ui/mysite/MySiteViewModel.kt 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk   #22813      +/-   ##
==========================================
- Coverage   37.34%   37.34%   -0.01%     
==========================================
  Files        2320     2321       +1     
  Lines      124653   124728      +75     
  Branches    16941    16962      +21     
==========================================
+ Hits        46549    46576      +27     
- Misses      74339    74385      +46     
- Partials     3765     3767       +2     

☔ View full report in Codecov by Sentry.
📢 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.

@jkmassel jkmassel force-pushed the jkmassel/gutenbergkit-opt-in branch 9 times, most recently from 3a28b0b to b87371c Compare May 26, 2026 18:06
Introduces a one-time announcement bottom sheet, shown on the next
WPMainActivity.onResume when the GutenbergKit remote feature is on,
the current site already defaults to the block editor, and the
announcement has not been shown before. The dialog's primary CTA
sets an app-wide opt-in flag (UndeletablePrefKey, persists across
logout); "Maybe later" dismisses without flipping it.

Site Settings gains a per-site GutenbergKit toggle, gated on the
same remote flag. The toggle is a tri-state override stored as two
StringSets (opt-in / opt-out / follow global), letting a user pin
a specific site on or off independent of the global opt-in.

Resolution order in GutenbergKitFeatureChecker: kill switch beats
everything; then siteOverride ?? globalOptIn ?? experimental ??
remote-feature decides. Threaded through EditorCapabilityResolver
so Theme Styles and Third-Party Blocks visibility / application
stays in agreement with whether the editor actually opens for the
site.
@jkmassel jkmassel force-pushed the jkmassel/gutenbergkit-opt-in branch from b87371c to 2bfdd30 Compare May 27, 2026 01:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants