Skip to content

Commit e923627

Browse files
refactor(mobile): showcase capture runs as an app service, not a chain of effects (#25857)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent a8edf13 commit e923627

6 files changed

Lines changed: 384 additions & 247 deletions

File tree

‎apps/mobile/src/App.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { ThreadArrangementHost } from "./features/threads/ThreadArrangementSheet
2424
import * as Dialog from "./components/ui/Dialog";
2525
import { CloudAuthProvider } from "./features/cloud/CloudAuthProvider";
2626
import { prepareNativeShowcaseCapture } from "./features/showcase/nativeShowcaseScene";
27+
import { installShowcaseCapture } from "./features/showcase/ShowcaseCaptureCoordinator";
2728
import {
2829
presentPendingIncomingShare,
2930
pruneIncomingShareImports,
@@ -42,7 +43,7 @@ import {
4243
installAppearanceRuntime,
4344
useAppearancePreferences,
4445
} from "./features/settings/appearance/AppearancePreferencesProvider";
45-
import { RootStack, workspaceLocationFromState } from "./Stack";
46+
import { RootStack, rootPathnameFromState, workspaceLocationFromState } from "./Stack";
4647
import { appAtomRegistry } from "./state/atom-registry";
4748
import { subscribeComposerDraftModelReconciliation } from "./state/use-composer-drafts";
4849
import { environmentThreadShells } from "./state/threads";
@@ -181,6 +182,7 @@ const appServiceDisposers = [
181182
installAgentNotificationNavigation(linkToAppPath),
182183
installAppShortcuts(linkToAppPath),
183184
installAppUpdateChecks(),
185+
installShowcaseCapture(rootPathnameFromState),
184186
];
185187
disposeOnFoundationReplace(typeof module === "undefined" ? undefined : module.hot, () => {
186188
for (const dispose of appServiceDisposers) dispose();

‎apps/mobile/src/Stack.tsx‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ import {
137137
isWorkspaceOverlayRoute,
138138
registerPresentedRoutes,
139139
} from "./features/layout/workspace-overlay-routes";
140-
import { ShowcaseCaptureCoordinator } from "./features/showcase/ShowcaseCaptureCoordinator";
140+
import { ShowcaseReadyMarker } from "./features/showcase/ShowcaseCaptureCoordinator";
141141
import {
142142
SettingsLegalDocumentCloseHeaderButton,
143143
SettingsLegalDocumentExternalHeaderButton,
@@ -492,12 +492,16 @@ export function workspaceLocationFromState(state: NavigationState) {
492492
};
493493
}
494494

495+
export function rootPathnameFromState(state: NavigationState): string {
496+
const path = getPathFromState(state, navigationPathConfig);
497+
return path.startsWith("/") ? path : `/${path}`;
498+
}
499+
495500
function RootStackLayout(props: {
496501
readonly children: React.ReactNode;
497502
readonly state: NavigationState;
498503
}) {
499-
const path = getPathFromState(props.state, navigationPathConfig);
500-
const pathname = path.startsWith("/") ? path : `/${path}`;
504+
const pathname = rootPathnameFromState(props.state);
501505
const workspaceLocation = workspaceLocationFromState(props.state);
502506
const settingsOpen = settingsOpenIn(
503507
props.state.routes
@@ -524,7 +528,7 @@ function RootStackLayout(props: {
524528
routeDraftId={routeDraftId}
525529
>
526530
<HardwareKeyboardCommandProvider pathname={pathname}>
527-
<ShowcaseCaptureCoordinator pathname={pathname} />
531+
<ShowcaseReadyMarker />
528532
<SettingsEnvironmentFilterProvider open={settingsOpen}>
529533
<WorkspaceConnectionStatusProvider>
530534
<AndroidWorkspaceTabsProvider state={props.state}>

‎apps/mobile/src/features/settings/appearance/AppearancePreferencesProvider.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ function resolveThemeVariablesByAppearance(
111111
}
112112

113113
/** The appearance whose theme is on screen, read from the native scheme. */
114-
function resolveThemeAppearance(stored: Preferences | null): MobileThemeAppearance {
114+
export function resolveThemeAppearance(stored: Preferences | null): MobileThemeAppearance {
115115
const themeMode = normalizeMobileThemeMode(stored?.themeMode);
116116
if (themeMode !== "system") return themeMode;
117117
return Appearance.getColorScheme() === "dark" ? "dark" : "light";

0 commit comments

Comments
 (0)