diff --git a/apps/desktop/src/components/layout/AppToolbar.vue b/apps/desktop/src/components/layout/AppToolbar.vue index 2ae16f45b5..ca0929766a 100644 --- a/apps/desktop/src/components/layout/AppToolbar.vue +++ b/apps/desktop/src/components/layout/AppToolbar.vue @@ -8,6 +8,7 @@ import LightDropdown from "@/components/ui/LightDropdown.vue"; import WindowControls from "@/components/layout/WindowControls.vue"; import ExportProgressPopover from "@/components/export/ExportProgressPopover.vue"; import { shouldReserveMacTrafficLightInset, useWindowControls } from "@/composables/useWindowControls"; +import { useToast } from "@/composables/useToast"; import { useSettingsStore } from "@/stores/settingsStore"; import type { AppThemeMode } from "@/lib/appTheme"; @@ -53,20 +54,34 @@ const emit = defineEmits<{ }>(); const { t } = useI18n(); +const { toast } = useToast(); const settingsStore = useSettingsStore(); const toolbarItems = computed(() => settingsStore.editorSettings.toolbarItems); const { isMac, isDesktop, showControls, isMaximized, isFullscreen, minimize, toggleMaximize, close } = useWindowControls(); -const themeItems = computed(() => [ - { value: "light", label: t("toolbar.themeLight"), icon: Sun }, - { value: "dark", label: t("toolbar.themeDark"), icon: Moon }, - { value: "system", label: t("toolbar.themeSystem"), icon: SunMoon }, -]); const themeTriggerIcon = computed(() => { if (props.themeMode === "system") return SunMoon; return props.isDark ? Moon : Sun; }); +function nextThemeMode(mode: AppThemeMode): AppThemeMode { + if (mode === "light") return "dark"; + if (mode === "dark") return "system"; + return "light"; +} + +function themeModeLabel(mode: AppThemeMode): string { + if (mode === "light") return t("toolbar.themeLight"); + if (mode === "dark") return t("toolbar.themeDark"); + return t("toolbar.themeSystem"); +} + +function cycleThemeMode() { + const next = nextThemeMode(props.themeMode); + emit("set-theme-mode", next); + toast(`${t("toolbar.theme")}: ${themeModeLabel(next)}`, 1600); +} + function onToolbarDblClick(e: MouseEvent) { if (isDesktop) return; const target = e.target as HTMLElement; @@ -149,8 +164,8 @@ const collapsibleRightItemDefs = computed(() => { items.push({ key: "theme", label: t("toolbar.theme"), - icon: SunMoon, - action: () => {}, + icon: themeTriggerIcon.value, + action: cycleThemeMode, disabled: false, }); } @@ -322,6 +337,16 @@ const collapsedItems = computed(() => { return items; }); +function runMoreItem(value: string) { + const item = moreItems.value.find((i) => i.value === value); + item?.action(); +} + +function runCollapsedItem(value: string) { + const item = collapsedItems.value.find((i) => i.value === value); + item?.action(); +} + // Per-item overflow visibility helper function isRightItemVisible(key: string) { return !overflowedRightKeys.value.has(key); @@ -368,12 +393,7 @@ const checkingUpdates = computed(() => props.checkingUpdates); :show-chevron="true" check-position="none" align="start" - @update:model-value=" - (value) => { - const item = moreItems.find((i) => i.value === value); - item?.action(); - } - " + @update:model-value="runMoreItem" /> @@ -389,12 +409,7 @@ const checkingUpdates = computed(() => props.checkingUpdates); :show-chevron="true" check-position="none" align="start" - @update:model-value=" - (value) => { - const item = collapsedItems.find((i) => i.value === value); - item?.action(); - } - " + @update:model-value="runCollapsedItem" /> @@ -448,22 +463,9 @@ const checkingUpdates = computed(() => props.checkingUpdates); - - - + {{ t("toolbar.theme") }}