fix(desktop): preserve theme when opening communities - #5266
Conversation
5dfeb30 to
1aa0619
Compare
Subscribe before fetching relay history, classify programmatic initialization even when appearance application is a no-op, and fail closed on missing or uncertain startup state so delayed replacements cannot be overwritten by an automatic fallback publish. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
1aa0619 to
65e5b25
Compare
wesbillman
left a comment
There was a problem hiding this comment.
Reviewing on Wes's behalf. The subscription-first arbitration is sound, but this patch removes the only successful-absence migration path entirely. On an account with no remote/local/outbox theme, hydration now does nothing: it neither persists the first community's inherited global appearance nor calls markCommunityThemeMigrated. Because that marker remains false, every later community with no record continues using initialPreferenceRef.current instead of the stable default, contrary to the controller's scope-isolation contract. This is a user-visible regression for accounts without an existing relay theme, not merely a documentation issue. Please preserve fail-closed behavior for uncertain states while adding a trustworthy confirmed-absence path that completes migration/seeding, and cover the controller-level sequence: first absent community migrates the inherited appearance; a later absent community receives DEFAULT_COMMUNITY_THEME rather than the first community's appearance. The PR body also currently says a default is seeded when neither source finds a preference, but this head never seeds on hydration.
Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz> Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
wesbillman
left a comment
There was a problem hiding this comment.
Reviewing on Wes's behalf. The code path is clean in my re-review, but the current head cannot merge under this repo's authorship policy: commit f79556b0ef37850cd7cfe3a63acf30fe23749e3b is authored and signed off by Carl. For block/buzz changes made on Wes's behalf, Wes must be the commit author and Signed-off-by, with the implementing agent only in Co-authored-by.
Please rewrite that commit so its author and sign-off are Wes <wesbillman@users.noreply.github.com>, retaining Carl as co-author, then force-push and let CI/DCO validate the rewritten head. This is my mistake from the implementation pass, not Taylor's.
Dismissed after re-review: the behavioral issue is fixed, and Wes explicitly accepts the current commit attribution.
wesbillman
left a comment
There was a problem hiding this comment.
Re-review by Carl on Wes's behalf at exact head f79556b0ef37850cd7cfe3a63acf30fe23749e3b: the prior behavioral blocker is fixed and no code findings remain. Wes explicitly accepts the current Carl-authored commit attribution, so I have dismissed both stale changes-requested reviews. The PR is mergeable and all applicable checks are green. Per policy, Wes retains approval authority.
* origin/main: chore: mesh upgrade, clean up legacy special case code, simplify model selection for mesh (#5289) fix(desktop): preserve theme when opening communities (#5266) fix(link-preview): resolve YouTube videos through oEmbed (#5520) fix(buzz-agent): harden Databricks OAuth token cache and callback (#5534) Signed-off-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Signed-off-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
…overy * origin/main: Add glass appearance and cohesive settings (#5478) Add Send to channel for thread messages (#5305) Fix macOS attachment picker lifecycle and allow inert HTML downloads (#5569) fix(desktop): preserve fresh channel timelines (#5577) fix(desktop): suppress fresh focus-return refetches for channels and home-feed (#5535) chore: mesh upgrade, clean up legacy special case code, simplify model selection for mesh (#5289) fix(desktop): preserve theme when opening communities (#5266) fix(link-preview): resolve YouTube videos through oEmbed (#5520) fix(buzz-agent): harden Databricks OAuth token cache and callback (#5534) Signed-off-by: Hardworking Honey <c5c455215c2506cb8ba776518cec804af62d3a0526e32d496a22072e395042b9@buzz.block.builderlab.xyz>
Bring in main's runtime.rs mesh acp_model wire translation so local checks and CI both run on the merged tree. Clean auto-merge; the PR's fail-closed spawn gating and main's model translation touch disjoint regions of spawn_agent_child. * origin/main: (24 commits) Improve desktop search scoping (#5306) Add glass appearance and cohesive settings (#5478) Add Send to channel for thread messages (#5305) Fix macOS attachment picker lifecycle and allow inert HTML downloads (#5569) fix(desktop): preserve fresh channel timelines (#5577) fix(desktop): suppress fresh focus-return refetches for channels and home-feed (#5535) chore: mesh upgrade, clean up legacy special case code, simplify model selection for mesh (#5289) fix(desktop): preserve theme when opening communities (#5266) fix(link-preview): resolve YouTube videos through oEmbed (#5520) fix(buzz-agent): harden Databricks OAuth token cache and callback (#5534) fix(link-preview): reliably render previews sent right after they resolve (#5245) fix(link-preview): restore Buzz entity link cards (#5494) chore(release): release Buzz Desktop version 0.5.9 (#5521) feat(cli): add --visibility flag to channels update (#5119) Polish desktop onboarding flow (#5310) fix(desktop): quiesce renderer polling while hidden (#3677) (#5490) fix(channels): restore member invitations to private channels (#5493) perf(ci): experiment with sccache for relay builds (#5224) fix(desktop): bound nine unbounded localStorage stores (#5454) feat(desktop): time-based sweep for stale localStorage caches (#5453) ... Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…overy * origin/main: Add glass appearance and cohesive settings (#5478) Add Send to channel for thread messages (#5305) Fix macOS attachment picker lifecycle and allow inert HTML downloads (#5569) fix(desktop): preserve fresh channel timelines (#5577) fix(desktop): suppress fresh focus-return refetches for channels and home-feed (#5535) chore: mesh upgrade, clean up legacy special case code, simplify model selection for mesh (#5289) fix(desktop): preserve theme when opening communities (#5266) fix(link-preview): resolve YouTube videos through oEmbed (#5520) fix(buzz-agent): harden Databricks OAuth token cache and callback (#5534) Signed-off-by: Hardworking Honey <c5c455215c2506cb8ba776518cec804af62d3a0526e32d496a22072e395042b9@buzz.block.builderlab.xyz>
Category: fix
User Impact: Previously selected community themes are preserved when opening a relay through onboarding, while first-time theme migration still completes for communities with no saved theme.
Problem: During community initialization, desktop queried theme history before establishing live delivery. If a replacement event arrived while an empty history query was in flight, the client could incorrectly treat the theme as absent and publish the default over the user's saved selection.
Solution: Subscribe before fetching history, expose whether live readiness reached EOSE, flush buffered live events before resolving EOSE, and retain the newest delivered replacement through hydration. Seed the inherited/default theme only when both live and history snapshots reach EOSE with no valid or unreadable event; subscription failures, CLOSED, readiness timeout, relay failure, and unreadable events fail closed without publishing.
File changes
desktop/src/shared/api/relayClientSession.ts / relayClientShared.ts / relayClosedRecovery.ts
Distinguish EOSE from CLOSED/timeout readiness and flush buffered events before resolving an EOSE fence.
desktop/src/shared/theme/CommunityThemeController.tsx
Seed and complete first-community migration only for confirmed absence; uncertain hydration remains non-publishing.
desktop/src/shared/theme/communityThemePreference.ts
Keep the inherited appearance for the first migrated community and the stable default for later empty communities.
desktop/src/shared/theme/communityThemeSync.ts
Arbitrate live and history results into valid, confirmed-absent, invalid, or unavailable hydration outcomes.
Tests
Cover EOSE/CLOSED readiness, subscription failure, timeout, unreadable and live-racing events, no-op initialization, and first-to-later community fallback isolation.
Reproduction steps
Validation
f79556b0e