fix(app): preserve persisted theme styles after startup
Module-level style composites could materialize the temporary adaptive theme before persisted settings loaded. Keep Unistyles reads in render and guard against eager module-scope access.
This commit is contained in:
@@ -210,8 +210,6 @@ function selectedSidebarItemStyle({ hovered }: PressableStateCallbackType & { ho
|
||||
];
|
||||
}
|
||||
|
||||
const ROW_WITH_BORDER_STYLE = [settingsStyles.row, settingsStyles.rowBorder];
|
||||
|
||||
function getSendBehaviorOptions(t: TFunction) {
|
||||
return [
|
||||
{ value: "interrupt" as const, label: t("settings.general.defaultSend.options.interrupt") },
|
||||
@@ -360,7 +358,7 @@ function GeneralSection({
|
||||
options={sendBehaviorOptions}
|
||||
/>
|
||||
</View>
|
||||
<View style={ROW_WITH_BORDER_STYLE}>
|
||||
<View style={[settingsStyles.row, settingsStyles.rowBorder]}>
|
||||
<View style={settingsStyles.rowContent}>
|
||||
<Text style={settingsStyles.rowTitle}>{t("settings.general.language.label")}</Text>
|
||||
<Text style={settingsStyles.rowHint}>{t("settings.general.language.description")}</Text>
|
||||
@@ -387,7 +385,7 @@ function GeneralSection({
|
||||
</DropdownMenu>
|
||||
</View>
|
||||
{isDesktopApp ? (
|
||||
<View style={ROW_WITH_BORDER_STYLE}>
|
||||
<View style={[settingsStyles.row, settingsStyles.rowBorder]}>
|
||||
<View style={settingsStyles.rowContent}>
|
||||
<Text style={settingsStyles.rowTitle}>{t("settings.general.serviceUrls.label")}</Text>
|
||||
<Text style={settingsStyles.rowHint}>
|
||||
@@ -414,7 +412,7 @@ function GeneralSection({
|
||||
</DropdownMenu>
|
||||
</View>
|
||||
) : null}
|
||||
<View style={ROW_WITH_BORDER_STYLE}>
|
||||
<View style={[settingsStyles.row, settingsStyles.rowBorder]}>
|
||||
<View style={settingsStyles.rowContent}>
|
||||
<Text style={settingsStyles.rowTitle}>
|
||||
{t("settings.general.terminalScrollback.label")}
|
||||
@@ -700,7 +698,7 @@ function DesktopAppUpdateRow() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={ROW_WITH_BORDER_STYLE}>
|
||||
<View style={[settingsStyles.row, settingsStyles.rowBorder]}>
|
||||
<View style={settingsStyles.rowContent}>
|
||||
<Text style={settingsStyles.rowTitle}>{t("settings.about.releaseChannel.label")}</Text>
|
||||
<Text style={settingsStyles.rowHint}>
|
||||
@@ -714,7 +712,7 @@ function DesktopAppUpdateRow() {
|
||||
options={releaseChannelOptions}
|
||||
/>
|
||||
</View>
|
||||
<View style={ROW_WITH_BORDER_STYLE}>
|
||||
<View style={[settingsStyles.row, settingsStyles.rowBorder]}>
|
||||
<View style={settingsStyles.rowContent}>
|
||||
<Text style={settingsStyles.rowTitle}>{t("settings.about.updates.label")}</Text>
|
||||
<Text style={settingsStyles.rowHint}>{statusText}</Text>
|
||||
|
||||
@@ -212,7 +212,6 @@ function AutoExpandReasoningRow({ value, onChange }: AutoExpandReasoningRowProps
|
||||
);
|
||||
}
|
||||
|
||||
const TOOL_CALL_DETAIL_ROW_STYLE = [settingsStyles.row, settingsStyles.rowBorder];
|
||||
const TOOL_CALL_DETAIL_LEVELS: readonly AppSettings["toolCallDetailLevel"][] = [
|
||||
"detailed",
|
||||
"overview",
|
||||
@@ -250,7 +249,7 @@ function ToolCallDetailRow({ value, onChange }: ToolCallDetailRowProps) {
|
||||
const { t } = useTranslation();
|
||||
const selectedLabel = getToolCallDetailLevelLabel(t, value);
|
||||
return (
|
||||
<View style={TOOL_CALL_DETAIL_ROW_STYLE}>
|
||||
<View style={[settingsStyles.row, settingsStyles.rowBorder]}>
|
||||
<View style={settingsStyles.rowContent}>
|
||||
<Text style={settingsStyles.rowTitle}>{t("settings.general.toolCallDetail.label")}</Text>
|
||||
<Text style={settingsStyles.rowHint}>
|
||||
|
||||
@@ -150,7 +150,7 @@ function HostNotFound() {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<View>
|
||||
<View style={EMPTY_CARD_STYLE}>
|
||||
<View style={[settingsStyles.card, styles.emptyCard]}>
|
||||
<Text style={styles.emptyText}>{t("settings.host.notFound")}</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -276,7 +276,7 @@ export function HostAgentsPage({ serverId }: { serverId: string }) {
|
||||
<AppendSystemPromptCard serverId={serverId} />
|
||||
</SettingsSection>
|
||||
) : (
|
||||
<View style={EMPTY_CARD_STYLE}>
|
||||
<View style={[settingsStyles.card, styles.emptyCard]}>
|
||||
<Text style={styles.emptyText}>{t("settings.host.agents.unavailable")}</Text>
|
||||
</View>
|
||||
)}
|
||||
@@ -300,7 +300,7 @@ export function HostWorkspacesPage({ serverId }: { serverId: string }) {
|
||||
<AutoArchiveMergedWorkspacesCard serverId={serverId} />
|
||||
</SettingsSection>
|
||||
) : (
|
||||
<View style={EMPTY_CARD_STYLE}>
|
||||
<View style={[settingsStyles.card, styles.emptyCard]}>
|
||||
<Text style={styles.emptyText}>{t("settings.host.workspaces.unavailable")}</Text>
|
||||
</View>
|
||||
)}
|
||||
@@ -1940,4 +1940,3 @@ const styles = StyleSheet.create((theme) => ({
|
||||
}));
|
||||
|
||||
const FLEX_1_STYLE = { flex: 1 };
|
||||
const EMPTY_CARD_STYLE = [settingsStyles.card, styles.emptyCard];
|
||||
|
||||
@@ -264,7 +264,7 @@ export function KeyboardShortcutsSection() {
|
||||
if (isNative) {
|
||||
return (
|
||||
<SettingsSection title={t("settings.sections.shortcuts")}>
|
||||
<View style={mobileCardStyle}>
|
||||
<View style={[settingsStyles.card, styles.mobileCard]}>
|
||||
<Text style={styles.mobileText}>{t("settings.shortcuts.unavailableOnMobile")}</Text>
|
||||
</View>
|
||||
</SettingsSection>
|
||||
@@ -362,5 +362,3 @@ const styles = StyleSheet.create((theme) => ({
|
||||
color: theme.colors.foregroundMuted,
|
||||
},
|
||||
}));
|
||||
|
||||
const mobileCardStyle = [settingsStyles.card, styles.mobileCard];
|
||||
|
||||
@@ -410,12 +410,12 @@ export function ProvidersSection({ serverId }: ProvidersSectionProps) {
|
||||
style={styles.sectionSpacing}
|
||||
>
|
||||
{!hasServer || !isConnected ? (
|
||||
<View style={EMPTY_CARD_STYLE}>
|
||||
<View style={[settingsStyles.card, styles.emptyCard]}>
|
||||
<Text style={styles.emptyText}>{t("settings.providers.unavailable")}</Text>
|
||||
</View>
|
||||
) : null}
|
||||
{hasServer && isConnected && isLoading ? (
|
||||
<View style={EMPTY_CARD_STYLE}>
|
||||
<View style={[settingsStyles.card, styles.emptyCard]}>
|
||||
<Text style={styles.emptyText}>{t("settings.providers.loading")}</Text>
|
||||
</View>
|
||||
) : null}
|
||||
@@ -543,5 +543,3 @@ const styles = StyleSheet.create((theme) => ({
|
||||
backgroundColor: theme.colors.surface3,
|
||||
},
|
||||
}));
|
||||
|
||||
const EMPTY_CARD_STYLE = [settingsStyles.card, styles.emptyCard];
|
||||
|
||||
@@ -1165,7 +1165,9 @@ function ResolvedDesktopTabChip({
|
||||
|
||||
return (
|
||||
<View style={styles.tabSlot}>
|
||||
{showDropIndicatorBefore ? <View style={TAB_DROP_INDICATOR_BEFORE_STYLE} /> : null}
|
||||
{showDropIndicatorBefore ? (
|
||||
<View style={[styles.tabDropIndicator, styles.tabDropIndicatorBefore]} />
|
||||
) : null}
|
||||
<TabChip
|
||||
tab={item.tab}
|
||||
isActive={item.isActive}
|
||||
@@ -1184,7 +1186,9 @@ function ResolvedDesktopTabChip({
|
||||
onCloseTab={onCloseTab}
|
||||
dragHandleProps={dragHandleProps}
|
||||
/>
|
||||
{showDropIndicatorAfter ? <View style={TAB_DROP_INDICATOR_AFTER_STYLE} /> : null}
|
||||
{showDropIndicatorAfter ? (
|
||||
<View style={[styles.tabDropIndicator, styles.tabDropIndicatorAfter]} />
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
}}
|
||||
@@ -1375,6 +1379,3 @@ const styles = StyleSheet.create((theme) => ({
|
||||
height: 14,
|
||||
},
|
||||
}));
|
||||
|
||||
const TAB_DROP_INDICATOR_BEFORE_STYLE = [styles.tabDropIndicator, styles.tabDropIndicatorBefore];
|
||||
const TAB_DROP_INDICATOR_AFTER_STYLE = [styles.tabDropIndicator, styles.tabDropIndicatorAfter];
|
||||
|
||||
@@ -3341,7 +3341,7 @@ function WorkspaceScreenContent({
|
||||
[t],
|
||||
);
|
||||
|
||||
const containerStyle = containerWithWorkspaceBackgroundStyle;
|
||||
const containerStyle = [styles.container, styles.containerWorkspaceBackground];
|
||||
|
||||
const menuNewAgentIcon = MENU_NEW_AGENT_ICON;
|
||||
const menuNewTerminalIcon = MENU_NEW_TERMINAL_ICON;
|
||||
@@ -4090,9 +4090,4 @@ const styles = StyleSheet.create((theme) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const containerWithWorkspaceBackgroundStyle = [
|
||||
styles.container,
|
||||
styles.containerWorkspaceBackground,
|
||||
];
|
||||
|
||||
const EXPLORER_TOGGLE_KEYS: ShortcutKey[] = ["mod", "E"];
|
||||
|
||||
@@ -88,7 +88,9 @@ function ScriptActionButtonChildren({
|
||||
) : (
|
||||
<ThemedPlay size={10} uniProps={colorMapping} {...playFillTransparent} />
|
||||
);
|
||||
const labelStyle = hovered ? actionButtonLabelHoveredStyle : styles.actionButtonLabel;
|
||||
const labelStyle = hovered
|
||||
? [styles.actionButtonLabel, styles.actionButtonLabelHovered]
|
||||
: styles.actionButtonLabel;
|
||||
return (
|
||||
<>
|
||||
{iconElement}
|
||||
@@ -156,7 +158,7 @@ function HostLinkChildren({ hovered, disabled, label }: HostLinkChildrenProps):
|
||||
const showIcon = !disabled && (hovered || isNative);
|
||||
const isActive = Boolean(hovered) && !disabled;
|
||||
const colorMapping = isActive ? foregroundColorMapping : mutedColorMapping;
|
||||
const hostLabelStyle = isActive ? hostLabelActiveStyle : styles.hostLabel;
|
||||
const hostLabelStyle = isActive ? [styles.hostLabel, styles.hostLabelActive] : styles.hostLabel;
|
||||
return (
|
||||
<>
|
||||
<Text style={hostLabelStyle} numberOfLines={1}>
|
||||
@@ -207,7 +209,8 @@ function HostLinkRow({ label, url, scriptName, onOpenInBrowserTab }: HostLinkPro
|
||||
|
||||
function ExitCodeBadge({ code }: { code: number }): ReactElement {
|
||||
const { t } = useTranslation();
|
||||
const exitTextStyle = code === 0 ? styles.exitBadgeText : exitBadgeTextErrorStyle;
|
||||
const exitTextStyle =
|
||||
code === 0 ? styles.exitBadgeText : [styles.exitBadgeText, styles.exitBadgeTextError];
|
||||
return (
|
||||
<View style={styles.exitBadge}>
|
||||
<Text style={exitTextStyle}>{t("workspace.scripts.states.exitCode", { code })}</Text>
|
||||
@@ -305,7 +308,7 @@ function ScriptRow({
|
||||
}, [onStartScript, script.scriptName]);
|
||||
|
||||
const scriptNameStyle = useMemo(
|
||||
() => (isRunning ? scriptNameActiveStyle : styles.scriptName),
|
||||
() => (isRunning ? [styles.scriptName, styles.scriptNameActive] : styles.scriptName),
|
||||
[isRunning],
|
||||
);
|
||||
|
||||
@@ -631,8 +634,3 @@ const styles = StyleSheet.create((theme) => ({
|
||||
color: theme.colors.foreground,
|
||||
},
|
||||
}));
|
||||
|
||||
const actionButtonLabelHoveredStyle = [styles.actionButtonLabel, styles.actionButtonLabelHovered];
|
||||
const hostLabelActiveStyle = [styles.hostLabel, styles.hostLabelActive];
|
||||
const scriptNameActiveStyle = [styles.scriptName, styles.scriptNameActive];
|
||||
const exitBadgeTextErrorStyle = [styles.exitBadgeText, styles.exitBadgeTextError];
|
||||
|
||||
Reference in New Issue
Block a user