mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 17:28:29 +02:00
Faster time-to-theme (#109)
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
import { Outlet } from 'react-router-dom';
|
import { Outlet } from 'react-router-dom';
|
||||||
import { useOsInfo } from '../hooks/useOsInfo';
|
import { useOsInfo } from '../hooks/useOsInfo';
|
||||||
import { DialogProvider, Dialogs } from './DialogContext';
|
import { DialogProvider, Dialogs } from './DialogContext';
|
||||||
@@ -16,17 +15,14 @@ export function DefaultLayout() {
|
|||||||
<Toasts />
|
<Toasts />
|
||||||
<Dialogs />
|
<Dialogs />
|
||||||
</>
|
</>
|
||||||
<motion.div
|
<div
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
transition={{ duration: 0.1, delay: 0.1 }}
|
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'w-full h-full',
|
'w-full h-full',
|
||||||
osInfo?.osType === 'linux' && 'border border-border-subtle',
|
osInfo?.osType === 'linux' && 'border border-border-subtle',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</motion.div>
|
</div>
|
||||||
<GlobalHooks />
|
<GlobalHooks />
|
||||||
</ToastProvider>
|
</ToastProvider>
|
||||||
</DialogProvider>
|
</DialogProvider>
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import { useRecentRequests } from '../hooks/useRecentRequests';
|
|||||||
import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces';
|
import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces';
|
||||||
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
||||||
import { settingsAtom, useSettings } from '../hooks/useSettings';
|
import { settingsAtom, useSettings } from '../hooks/useSettings';
|
||||||
import { useSyncThemeToDocument } from '../hooks/useSyncThemeToDocument';
|
|
||||||
import { useToggleCommandPalette } from '../hooks/useToggleCommandPalette';
|
import { useToggleCommandPalette } from '../hooks/useToggleCommandPalette';
|
||||||
import { workspacesAtom } from '../hooks/useWorkspaces';
|
import { workspacesAtom } from '../hooks/useWorkspaces';
|
||||||
import { useZoom } from '../hooks/useZoom';
|
import { useZoom } from '../hooks/useZoom';
|
||||||
@@ -39,6 +38,11 @@ import { rosePineDefault } from '../lib/theme/themes/rose-pine';
|
|||||||
import { yaakDark } from '../lib/theme/themes/yaak';
|
import { yaakDark } from '../lib/theme/themes/yaak';
|
||||||
import { getThemeCSS } from '../lib/theme/window';
|
import { getThemeCSS } from '../lib/theme/window';
|
||||||
|
|
||||||
|
export interface ModelPayload {
|
||||||
|
model: AnyModel;
|
||||||
|
windowLabel: string;
|
||||||
|
}
|
||||||
|
|
||||||
export function GlobalHooks() {
|
export function GlobalHooks() {
|
||||||
// Include here so they always update, even if no component references them
|
// Include here so they always update, even if no component references them
|
||||||
useRecentWorkspaces();
|
useRecentWorkspaces();
|
||||||
@@ -47,7 +51,6 @@ export function GlobalHooks() {
|
|||||||
useRecentRequests();
|
useRecentRequests();
|
||||||
|
|
||||||
// Other useful things
|
// Other useful things
|
||||||
useSyncThemeToDocument();
|
|
||||||
useNotificationToast();
|
useNotificationToast();
|
||||||
useActiveWorkspaceChangedToast();
|
useActiveWorkspaceChangedToast();
|
||||||
useEnsureActiveCookieJar();
|
useEnsureActiveCookieJar();
|
||||||
@@ -61,11 +64,6 @@ export function GlobalHooks() {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { wasUpdatedExternally } = useRequestUpdateKey(null);
|
const { wasUpdatedExternally } = useRequestUpdateKey(null);
|
||||||
|
|
||||||
interface ModelPayload {
|
|
||||||
model: AnyModel;
|
|
||||||
windowLabel: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const setSettings = useSetAtom(settingsAtom);
|
const setSettings = useSetAtom(settingsAtom);
|
||||||
const setWorkspaces = useSetAtom(workspacesAtom);
|
const setWorkspaces = useSetAtom(workspacesAtom);
|
||||||
const setPlugins = useSetAtom(pluginsAtom);
|
const setPlugins = useSetAtom(pluginsAtom);
|
||||||
|
|||||||
@@ -117,9 +117,11 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ
|
|||||||
>
|
>
|
||||||
{activeResponse && (
|
{activeResponse && (
|
||||||
<HStack
|
<HStack
|
||||||
as="p"
|
|
||||||
space={2}
|
space={2}
|
||||||
className="whitespace-nowrap w-full pl-3 overflow-x-auto font-mono text-sm"
|
className={classNames(
|
||||||
|
'cursor-default select-none',
|
||||||
|
'whitespace-nowrap w-full pl-3 overflow-x-auto font-mono text-sm',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<StatusTag showReason response={activeResponse} />
|
<StatusTag showReason response={activeResponse} />
|
||||||
{activeResponse.elapsed > 0 && (
|
{activeResponse.elapsed > 0 && (
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import { useActiveWorkspace } from '../../hooks/useActiveWorkspace';
|
|||||||
import { useResolvedAppearance } from '../../hooks/useResolvedAppearance';
|
import { useResolvedAppearance } from '../../hooks/useResolvedAppearance';
|
||||||
import { useResolvedTheme } from '../../hooks/useResolvedTheme';
|
import { useResolvedTheme } from '../../hooks/useResolvedTheme';
|
||||||
import { useSettings } from '../../hooks/useSettings';
|
import { useSettings } from '../../hooks/useSettings';
|
||||||
import { useThemes } from '../../hooks/useThemes';
|
|
||||||
import { useUpdateSettings } from '../../hooks/useUpdateSettings';
|
import { useUpdateSettings } from '../../hooks/useUpdateSettings';
|
||||||
import { trackEvent } from '../../lib/analytics';
|
import { trackEvent } from '../../lib/analytics';
|
||||||
import { clamp } from '../../lib/clamp';
|
import { clamp } from '../../lib/clamp';
|
||||||
|
import { getThemes } from '../../lib/theme/themes';
|
||||||
import { isThemeDark } from '../../lib/theme/window';
|
import { isThemeDark } from '../../lib/theme/window';
|
||||||
import type { ButtonProps } from '../core/Button';
|
import type { ButtonProps } from '../core/Button';
|
||||||
import { Checkbox } from '../core/Checkbox';
|
import { Checkbox } from '../core/Checkbox';
|
||||||
@@ -52,12 +52,13 @@ const icons: IconProps['icon'][] = [
|
|||||||
'send_horizontal',
|
'send_horizontal',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const { themes } = getThemes();
|
||||||
|
|
||||||
export function SettingsAppearance() {
|
export function SettingsAppearance() {
|
||||||
const workspace = useActiveWorkspace();
|
const workspace = useActiveWorkspace();
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
const updateSettings = useUpdateSettings();
|
const updateSettings = useUpdateSettings();
|
||||||
const appearance = useResolvedAppearance();
|
const appearance = useResolvedAppearance();
|
||||||
const { themes } = useThemes();
|
|
||||||
const activeTheme = useResolvedTheme();
|
const activeTheme = useResolvedTheme();
|
||||||
|
|
||||||
if (settings == null || workspace == null) {
|
if (settings == null || workspace == null) {
|
||||||
@@ -161,9 +162,10 @@ export function SettingsAppearance() {
|
|||||||
space={3}
|
space={3}
|
||||||
className="mt-3 w-full bg-surface p-3 border border-dashed border-border-subtle rounded overflow-x-auto"
|
className="mt-3 w-full bg-surface p-3 border border-dashed border-border-subtle rounded overflow-x-auto"
|
||||||
>
|
>
|
||||||
<HStack className="text font-bold" space={2}>
|
<HStack className="text" space={1.5}>
|
||||||
Theme Preview{' '}
|
|
||||||
<Icon icon={appearance === 'dark' ? 'moon' : 'sun'} className="text-text-subtle" />
|
<Icon icon={appearance === 'dark' ? 'moon' : 'sun'} className="text-text-subtle" />
|
||||||
|
<strong>{activeTheme.active.name}</strong>
|
||||||
|
<em>(preview)</em>
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack space={1.5} className="w-full">
|
<HStack space={1.5} className="w-full">
|
||||||
{buttonColors.map((c, i) => (
|
{buttonColors.map((c, i) => (
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { open } from '@tauri-apps/plugin-dialog';
|
import { open } from '@tauri-apps/plugin-dialog';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useLocalStorage } from 'react-use';
|
import { useLocalStorage } from 'react-use';
|
||||||
import { useThemes } from '../../hooks/useThemes';
|
|
||||||
import { capitalize } from '../../lib/capitalize';
|
import { capitalize } from '../../lib/capitalize';
|
||||||
import { invokeCmd } from '../../lib/tauri';
|
import { invokeCmd } from '../../lib/tauri';
|
||||||
|
import { getThemes } from '../../lib/theme/themes';
|
||||||
import { yaakDark } from '../../lib/theme/themes/yaak';
|
import { yaakDark } from '../../lib/theme/themes/yaak';
|
||||||
import { getThemeCSS } from '../../lib/theme/window';
|
import { getThemeCSS } from '../../lib/theme/window';
|
||||||
import { Banner } from '../core/Banner';
|
import { Banner } from '../core/Banner';
|
||||||
@@ -45,9 +45,9 @@ const icons: IconProps['icon'][] = [
|
|||||||
'send_horizontal',
|
'send_horizontal',
|
||||||
];
|
];
|
||||||
|
|
||||||
export function SettingsDesign() {
|
const themes = getThemes();
|
||||||
const themes = useThemes();
|
|
||||||
|
|
||||||
|
export function SettingsDesign() {
|
||||||
const [exportDir, setExportDir] = useLocalStorage<string | null>('theme_export_dir', null);
|
const [exportDir, setExportDir] = useLocalStorage<string | null>('theme_export_dir', null);
|
||||||
const [loadingExport, setLoadingExport] = useState<boolean>(false);
|
const [loadingExport, setLoadingExport] = useState<boolean>(false);
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,9 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import type { Appearance } from '../lib/theme/appearance';
|
import type { Appearance } from '../lib/theme/appearance';
|
||||||
import {
|
import { getCSSAppearance, subscribeToPreferredAppearance } from '../lib/theme/appearance';
|
||||||
getCSSAppearance,
|
|
||||||
getWindowAppearance,
|
|
||||||
subscribeToWindowAppearanceChange,
|
|
||||||
} from '../lib/theme/appearance';
|
|
||||||
|
|
||||||
export function usePreferredAppearance() {
|
export function usePreferredAppearance() {
|
||||||
const [preferredAppearance, setPreferredAppearance] = useState<Appearance>(getCSSAppearance());
|
const [preferredAppearance, setPreferredAppearance] = useState<Appearance>(getCSSAppearance());
|
||||||
|
useEffect(() => subscribeToPreferredAppearance(setPreferredAppearance), []);
|
||||||
useEffect(() => {
|
|
||||||
getWindowAppearance().then(setPreferredAppearance);
|
|
||||||
return subscribeToWindowAppearanceChange(setPreferredAppearance);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return preferredAppearance;
|
return preferredAppearance;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
|
import { resolveAppearance } from '../lib/theme/appearance';
|
||||||
import { usePreferredAppearance } from './usePreferredAppearance';
|
import { usePreferredAppearance } from './usePreferredAppearance';
|
||||||
import { useSettings } from './useSettings';
|
import { useSettings } from './useSettings';
|
||||||
|
|
||||||
export function useResolvedAppearance() {
|
export function useResolvedAppearance() {
|
||||||
const preferredAppearance = usePreferredAppearance();
|
const preferredAppearance = usePreferredAppearance();
|
||||||
|
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
const appearance =
|
return resolveAppearance(preferredAppearance, settings.appearance);
|
||||||
settings == null || settings?.appearance === 'system'
|
|
||||||
? preferredAppearance
|
|
||||||
: settings.appearance;
|
|
||||||
|
|
||||||
return appearance;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
import { isThemeDark } from '../lib/theme/window';
|
import { getResolvedTheme } from '../lib/theme/themes';
|
||||||
import { useResolvedAppearance } from './useResolvedAppearance';
|
import { usePreferredAppearance } from './usePreferredAppearance';
|
||||||
import { useSettings } from './useSettings';
|
import { useSettings } from './useSettings';
|
||||||
import { useThemes } from './useThemes';
|
|
||||||
|
|
||||||
export function useResolvedTheme() {
|
export function useResolvedTheme() {
|
||||||
const appearance = useResolvedAppearance();
|
const preferredAppearance = usePreferredAppearance();
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
const { themes, fallback } = useThemes();
|
return getResolvedTheme(
|
||||||
|
preferredAppearance,
|
||||||
const darkThemes = themes.filter((t) => isThemeDark(t));
|
settings.appearance,
|
||||||
const lightThemes = themes.filter((t) => !isThemeDark(t));
|
settings.themeLight,
|
||||||
|
settings.themeDark,
|
||||||
const dark = darkThemes.find((t) => t.id === settings?.themeDark) ?? fallback.dark;
|
);
|
||||||
const light = lightThemes.find((t) => t.id === settings?.themeLight) ?? fallback.light;
|
|
||||||
|
|
||||||
const active = appearance === 'dark' ? dark : light;
|
|
||||||
|
|
||||||
return { dark, light, active };
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
import { emit } from '@tauri-apps/api/event';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
import type { YaakTheme } from '../lib/theme/window';
|
|
||||||
import { addThemeStylesToDocument, setThemeOnDocument } from '../lib/theme/window';
|
|
||||||
import { useResolvedTheme } from './useResolvedTheme';
|
|
||||||
|
|
||||||
export function useSyncThemeToDocument() {
|
|
||||||
const theme = useResolvedTheme();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setThemeOnDocument(theme.active);
|
|
||||||
emitBgChange(theme.active);
|
|
||||||
}, [theme.active]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
addThemeStylesToDocument(theme.active);
|
|
||||||
}, [theme.active]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitBgChange(t: YaakTheme) {
|
|
||||||
if (t.surface == null) return;
|
|
||||||
emit('yaak_bg_changed', t.surface.hexNoAlpha()).catch(console.error);
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { defaultDarkTheme, defaultLightTheme, yaakThemes } from '../lib/theme/themes';
|
|
||||||
|
|
||||||
export function useThemes() {
|
|
||||||
const dark = defaultDarkTheme;
|
|
||||||
const light = defaultLightTheme;
|
|
||||||
|
|
||||||
const otherThemes = yaakThemes
|
|
||||||
.filter((t) => t.id !== dark.id && t.id !== light.id)
|
|
||||||
.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
|
|
||||||
const themes = [dark, light, ...otherThemes];
|
|
||||||
return { themes, fallback: { dark, light } };
|
|
||||||
}
|
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
<div id="cm-portal" class="cm-portal"></div>
|
<div id="cm-portal" class="cm-portal"></div>
|
||||||
<div id="react-portal"></div>
|
<div id="react-portal"></div>
|
||||||
<div id="radix-portal" class="cm-portal"></div>
|
<div id="radix-portal" class="cm-portal"></div>
|
||||||
|
<script type="module" src="/theme.ts"></script>
|
||||||
<script type="module" src="/main.tsx"></script>
|
<script type="module" src="/main.tsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ export async function getWindowAppearance(): Promise<Appearance> {
|
|||||||
export function subscribeToWindowAppearanceChange(
|
export function subscribeToWindowAppearanceChange(
|
||||||
cb: (appearance: Appearance) => void,
|
cb: (appearance: Appearance) => void,
|
||||||
): () => void {
|
): () => void {
|
||||||
const container = { unsubscribe: () => {} };
|
const container = {
|
||||||
|
unsubscribe: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
getCurrentWebviewWindow()
|
getCurrentWebviewWindow()
|
||||||
.onThemeChanged((t) => {
|
.onThemeChanged((t) => {
|
||||||
@@ -30,3 +32,17 @@ export function subscribeToWindowAppearanceChange(
|
|||||||
|
|
||||||
return () => container.unsubscribe();
|
return () => container.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveAppearance(
|
||||||
|
preferredAppearance: Appearance,
|
||||||
|
appearanceSetting: string,
|
||||||
|
): Appearance {
|
||||||
|
const appearance = appearanceSetting === 'system' ? preferredAppearance : appearanceSetting;
|
||||||
|
return appearance === 'dark' ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function subscribeToPreferredAppearance(cb: (a: Appearance) => void) {
|
||||||
|
cb(getCSSAppearance());
|
||||||
|
getWindowAppearance().then(cb);
|
||||||
|
subscribeToWindowAppearanceChange(cb);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import type { Appearance } from './appearance';
|
||||||
|
import { resolveAppearance } from './appearance';
|
||||||
import { catppuccin } from './themes/catppuccin';
|
import { catppuccin } from './themes/catppuccin';
|
||||||
import { github } from './themes/github';
|
import { github } from './themes/github';
|
||||||
import { hotdogStand } from './themes/hotdog-stand';
|
import { hotdogStand } from './themes/hotdog-stand';
|
||||||
@@ -5,11 +7,12 @@ import { monokaiPro } from './themes/monokai-pro';
|
|||||||
import { relaxing } from './themes/relaxing';
|
import { relaxing } from './themes/relaxing';
|
||||||
import { rosePine } from './themes/rose-pine';
|
import { rosePine } from './themes/rose-pine';
|
||||||
import { yaak, yaakDark, yaakLight } from './themes/yaak';
|
import { yaak, yaakDark, yaakLight } from './themes/yaak';
|
||||||
|
import { isThemeDark } from './window';
|
||||||
|
|
||||||
export const defaultDarkTheme = yaakDark;
|
export const defaultDarkTheme = yaakDark;
|
||||||
export const defaultLightTheme = yaakLight;
|
export const defaultLightTheme = yaakLight;
|
||||||
|
|
||||||
export const yaakThemes = [
|
const allThemes = [
|
||||||
...yaak,
|
...yaak,
|
||||||
...catppuccin,
|
...catppuccin,
|
||||||
...relaxing,
|
...relaxing,
|
||||||
@@ -18,3 +21,35 @@ export const yaakThemes = [
|
|||||||
...monokaiPro,
|
...monokaiPro,
|
||||||
...hotdogStand,
|
...hotdogStand,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export function getThemes() {
|
||||||
|
const dark = defaultDarkTheme;
|
||||||
|
const light = defaultLightTheme;
|
||||||
|
|
||||||
|
const otherThemes = allThemes
|
||||||
|
.filter((t) => t.id !== dark.id && t.id !== light.id)
|
||||||
|
.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
|
||||||
|
const themes = [dark, light, ...otherThemes];
|
||||||
|
return { themes, fallback: { dark, light } };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getResolvedTheme(
|
||||||
|
preferredAppearance: Appearance,
|
||||||
|
appearanceSetting: string,
|
||||||
|
themeLight: string,
|
||||||
|
themeDark: string,
|
||||||
|
) {
|
||||||
|
const appearance = resolveAppearance(preferredAppearance, appearanceSetting);
|
||||||
|
const { themes, fallback } = getThemes();
|
||||||
|
|
||||||
|
const darkThemes = themes.filter((t) => isThemeDark(t));
|
||||||
|
const lightThemes = themes.filter((t) => !isThemeDark(t));
|
||||||
|
|
||||||
|
const dark = darkThemes.find((t) => t.id === themeDark) ?? fallback.dark;
|
||||||
|
const light = lightThemes.find((t) => t.id === themeLight) ?? fallback.light;
|
||||||
|
|
||||||
|
const active = appearance === 'dark' ? dark : light;
|
||||||
|
|
||||||
|
return { dark, light, active };
|
||||||
|
}
|
||||||
|
|||||||
45
src-web/theme.ts
Normal file
45
src-web/theme.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { emit, listen } from '@tauri-apps/api/event';
|
||||||
|
import type { ModelPayload } from './components/GlobalHooks';
|
||||||
|
import { getSettings } from './lib/store';
|
||||||
|
import type {
|
||||||
|
Appearance} from './lib/theme/appearance';
|
||||||
|
import {
|
||||||
|
getCSSAppearance,
|
||||||
|
subscribeToPreferredAppearance,
|
||||||
|
} from './lib/theme/appearance';
|
||||||
|
import { getResolvedTheme } from './lib/theme/themes';
|
||||||
|
import type { YaakTheme } from './lib/theme/window';
|
||||||
|
import { addThemeStylesToDocument, setThemeOnDocument } from './lib/theme/window';
|
||||||
|
|
||||||
|
// NOTE: CSS appearance isn't as accurate as getting it async from the window (next step), but we want
|
||||||
|
// a good appearance guess so we're not waiting too long
|
||||||
|
let preferredAppearance: Appearance = getCSSAppearance();
|
||||||
|
subscribeToPreferredAppearance(async (a) => {
|
||||||
|
preferredAppearance = a;
|
||||||
|
await configureTheme();
|
||||||
|
});
|
||||||
|
configureTheme().catch(console.error);
|
||||||
|
|
||||||
|
// Listen for settings changes, the re-compute theme
|
||||||
|
listen<ModelPayload>('upserted_model', async (event) => {
|
||||||
|
if (event.payload.model.model !== 'settings') return;
|
||||||
|
await configureTheme();
|
||||||
|
}).catch(console.error);
|
||||||
|
|
||||||
|
async function configureTheme() {
|
||||||
|
const settings = await getSettings();
|
||||||
|
const theme = getResolvedTheme(
|
||||||
|
preferredAppearance,
|
||||||
|
settings.appearance,
|
||||||
|
settings.themeLight,
|
||||||
|
settings.themeDark,
|
||||||
|
);
|
||||||
|
addThemeStylesToDocument(theme.active);
|
||||||
|
setThemeOnDocument(theme.active);
|
||||||
|
emitBgChange(theme.active);
|
||||||
|
}
|
||||||
|
|
||||||
|
function emitBgChange(t: YaakTheme) {
|
||||||
|
if (t.surface == null) return;
|
||||||
|
emit('yaak_bg_changed', t.surface.hexNoAlpha()).catch(console.error);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user