Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions desktop/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ language = "zh"
theme = "light"
theme_style = "glacier"
close_behavior = "quit"
status_bar_style = "icon"
status_bar_items = ["cost", "balance"]
`), 0o644); err != nil {
t.Fatalf("write project config: %v", err)
}
Expand All @@ -242,6 +244,12 @@ close_behavior = "quit"
if err := userCfg.SetDesktopCloseBehavior("background"); err != nil {
t.Fatalf("set desktop close behavior: %v", err)
}
if err := userCfg.SetDesktopStatusBarStyle("text"); err != nil {
t.Fatalf("set desktop status bar style: %v", err)
}
if err := userCfg.SetDesktopStatusBarItems([]string{"model", "balance", "cache"}); err != nil {
t.Fatalf("set desktop status bar items: %v", err)
}
if err := userCfg.SaveTo(config.UserConfigPath()); err != nil {
t.Fatalf("save user config: %v", err)
}
Expand All @@ -253,8 +261,11 @@ close_behavior = "quit"
}

got := NewApp().Settings()
if got.DesktopLanguage != "en" || got.DesktopTheme != "dark" || got.DesktopThemeStyle != "graphite" || got.CloseBehavior != "background" {
t.Fatalf("desktop settings = lang:%q theme:%q style:%q close:%q, want user-level desktop prefs", got.DesktopLanguage, got.DesktopTheme, got.DesktopThemeStyle, got.CloseBehavior)
if got.DesktopLanguage != "en" || got.DesktopTheme != "dark" || got.DesktopThemeStyle != "graphite" || got.CloseBehavior != "background" || got.StatusBarStyle != "text" {
t.Fatalf("desktop settings = lang:%q theme:%q style:%q close:%q status:%q, want user-level desktop prefs", got.DesktopLanguage, got.DesktopTheme, got.DesktopThemeStyle, got.CloseBehavior, got.StatusBarStyle)
}
if want := []string{"model", "balance", "cache"}; !reflect.DeepEqual(got.StatusBarItems, want) {
t.Fatalf("desktop status bar items = %v, want user-level %v", got.StatusBarItems, want)
}
}

Expand All @@ -270,6 +281,8 @@ language = "zh"
theme = "light"
theme_style = "glacier"
close_behavior = "quit"
status_bar_style = "text"
status_bar_items = ["model", "cache", "balance"]
`), 0o644); err != nil {
t.Fatalf("write project config: %v", err)
}
Expand All @@ -285,18 +298,24 @@ close_behavior = "quit"
if got.ConfigPath != config.UserConfigPath() {
t.Fatalf("Settings configPath = %q, want user config %q", got.ConfigPath, config.UserConfigPath())
}
if got.DefaultModel != "legacy-provider/legacy-model" || got.DesktopLanguage != "zh" || got.DesktopTheme != "light" || got.DesktopThemeStyle != "glacier" || got.CloseBehavior != "quit" {
if got.DefaultModel != "legacy-provider/legacy-model" || got.DesktopLanguage != "zh" || got.DesktopTheme != "light" || got.DesktopThemeStyle != "glacier" || got.CloseBehavior != "quit" || got.StatusBarStyle != "text" {
t.Fatalf("Settings did not seed from legacy project config: %+v", got)
}
if want := []string{"model", "cache", "balance"}; !reflect.DeepEqual(got.StatusBarItems, want) {
t.Fatalf("Settings did not seed status bar items from legacy project config: got %v want %v", got.StatusBarItems, want)
}
if _, err := os.Stat(config.UserConfigPath()); !os.IsNotExist(err) {
t.Fatalf("Settings() should not write user config before an edit, stat err = %v", err)
}
if err := app.SetDesktopLanguage("en"); err != nil {
t.Fatalf("SetDesktopLanguage: %v", err)
}
userCfg := config.LoadForEdit(config.UserConfigPath())
if userCfg.DesktopLanguage() != "en" || userCfg.DesktopTheme() != "light" || userCfg.DesktopThemeStyle() != "glacier" || userCfg.DesktopCloseBehavior() != "quit" {
t.Fatalf("saved user config did not preserve seeded desktop prefs: lang:%q theme:%q style:%q close:%q", userCfg.DesktopLanguage(), userCfg.DesktopTheme(), userCfg.DesktopThemeStyle(), userCfg.DesktopCloseBehavior())
if userCfg.DesktopLanguage() != "en" || userCfg.DesktopTheme() != "light" || userCfg.DesktopThemeStyle() != "glacier" || userCfg.DesktopCloseBehavior() != "quit" || userCfg.DesktopStatusBarStyle() != "text" {
t.Fatalf("saved user config did not preserve seeded desktop prefs: lang:%q theme:%q style:%q close:%q status:%q", userCfg.DesktopLanguage(), userCfg.DesktopTheme(), userCfg.DesktopThemeStyle(), userCfg.DesktopCloseBehavior(), userCfg.DesktopStatusBarStyle())
}
if want := []string{"model", "cache", "balance"}; !reflect.DeepEqual(userCfg.DesktopStatusBarItems(), want) {
t.Fatalf("saved user config did not preserve seeded status bar items: got %v want %v", userCfg.DesktopStatusBarItems(), want)
}
}

Expand Down
10 changes: 9 additions & 1 deletion desktop/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import {
} from "./lib/toolApprovalMode";
import { loadLayoutSize, saveLayoutSize } from "./lib/layoutPreferences";
import { hydrateDisplayMode } from "./lib/displayMode";
import { DEFAULT_STATUS_BAR_ITEMS, normalizeStatusBarItems, type StatusBarItemId } from "./lib/statusBarItems";
import { blobToBase64, renderSessionImageBlob, renderSessionPdfBlob } from "./lib/sessionExport";
import { sessionActivityTime } from "./lib/session";
import {
Expand Down Expand Up @@ -727,6 +728,8 @@ export default function App() {
const [transientOverlayDismissSignal, setTransientOverlayDismissSignal] = useState(0);
const [desktopPlatform, setDesktopPlatform] = useState<DesktopPlatform>(detectBrowserPlatform);
const [expandThinking, setExpandThinking] = useState(false);
const [statusBarStyle, setStatusBarStyle] = useState<"icon" | "text">("text");
const [statusBarItems, setStatusBarItems] = useState<StatusBarItemId[]>(() => [...DEFAULT_STATUS_BAR_ITEMS]);
const [renamingTopicId, setRenamingTopicId] = useState<string | null>(null);
const [topicTitleDraft, setTopicTitleDraft] = useState("");
const [topicExportOpen, setTopicExportOpen] = useState(false);
Expand Down Expand Up @@ -845,12 +848,14 @@ export default function App() {
}, []);

const applyDesktopPreferences = useCallback(
(settings: Pick<SettingsView, "desktopTheme" | "desktopThemeStyle" | "desktopLanguage" | "checkUpdates">) => {
(settings: Pick<SettingsView, "desktopTheme" | "desktopThemeStyle" | "desktopLanguage" | "checkUpdates" | "statusBarStyle" | "statusBarItems">) => {
const nextTheme = normalizeThemePreference(settings.desktopTheme);
const nextStyle = normalizeThemeStyleForTheme(settings.desktopThemeStyle, nextTheme);
applyTheme(nextTheme, nextStyle, { persist: false });
setLocalePref(normalizeLangPref(settings.desktopLanguage));
setStartupUpdateChecksEnabled(settings.checkUpdates !== false);
setStatusBarStyle(settings.statusBarStyle === "text" ? "text" : "icon");
setStatusBarItems(normalizeStatusBarItems(settings.statusBarItems));
},
[setLocalePref],
);
Expand Down Expand Up @@ -2638,9 +2643,12 @@ export default function App() {
sessionTurns={sessionTurns}
sessionTokens={state.sessionTokens}
turnTokens={state.turnTotalTokens}
turnCost={state.turnCost}
cost={state.sessionCost}
currency={state.sessionCurrency}
modelLabel={state.meta?.label}
labelStyle={statusBarStyle}
items={statusBarItems}
/>
</footer>
)}
Expand Down
Loading
Loading