forked from akanyan/STARTLINER
feat: theme switcher
This commit is contained in:
@ -1,3 +1,7 @@
|
|||||||
|
## 0.9.0
|
||||||
|
|
||||||
|
- Added a light/dark theme switcher
|
||||||
|
|
||||||
## 0.8.1
|
## 0.8.1
|
||||||
|
|
||||||
- Hotfixed the program failing to launch if the data dir hadn't already been created
|
- Hotfixed the program failing to launch if the data dir hadn't already been created
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "STARTLINER",
|
"productName": "STARTLINER",
|
||||||
"version": "0.8.1",
|
"version": "0.9.0",
|
||||||
"identifier": "zip.patafour.startliner",
|
"identifier": "zip.patafour.startliner",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "bun run dev",
|
"beforeDevCommand": "bun run dev",
|
||||||
|
@ -28,7 +28,9 @@ import {
|
|||||||
usePrfStore,
|
usePrfStore,
|
||||||
} from '../stores';
|
} from '../stores';
|
||||||
import { Dirs } from '../types';
|
import { Dirs } from '../types';
|
||||||
import { messageSplit } from '../util';
|
import { messageSplit, shouldPreferDark } from '../util';
|
||||||
|
|
||||||
|
document.documentElement.classList.toggle('use-dark-mode', shouldPreferDark());
|
||||||
|
|
||||||
const pkg = usePkgStore();
|
const pkg = usePkgStore();
|
||||||
const prf = usePrfStore();
|
const prf = usePrfStore();
|
||||||
|
@ -34,6 +34,15 @@ const verboseModel = computed({
|
|||||||
await client.setVerbose(value);
|
await client.setVerbose(value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const themeModel = computed({
|
||||||
|
get() {
|
||||||
|
return client.theme;
|
||||||
|
},
|
||||||
|
async set(value: 'light' | 'dark' | 'system') {
|
||||||
|
await client.setTheme(value);
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -67,5 +76,18 @@ const verboseModel = computed({
|
|||||||
>
|
>
|
||||||
<ToggleSwitch v-model="verboseModel" />
|
<ToggleSwitch v-model="verboseModel" />
|
||||||
</OptionRow>
|
</OptionRow>
|
||||||
|
<OptionRow title="Light theme">
|
||||||
|
<SelectButton
|
||||||
|
v-model="themeModel"
|
||||||
|
:options="[
|
||||||
|
{ title: 'System', value: 'system' },
|
||||||
|
{ title: 'Light', value: 'light' },
|
||||||
|
{ title: 'Dark', value: 'dark' },
|
||||||
|
]"
|
||||||
|
:allow-empty="false"
|
||||||
|
option-label="title"
|
||||||
|
option-value="value"
|
||||||
|
/>
|
||||||
|
</OptionRow>
|
||||||
</OptionCategory>
|
</OptionCategory>
|
||||||
</template>
|
</template>
|
||||||
|
@ -17,6 +17,9 @@ app.use(pinia);
|
|||||||
app.use(PrimeVue, {
|
app.use(PrimeVue, {
|
||||||
theme: {
|
theme: {
|
||||||
preset: Preset,
|
preset: Preset,
|
||||||
|
options: {
|
||||||
|
darkModeSelector: '.use-dark-mode',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
app.use(ConfirmationService);
|
app.use(ConfirmationService);
|
||||||
|
@ -6,7 +6,12 @@ import { PhysicalSize, getCurrentWindow } from '@tauri-apps/api/window';
|
|||||||
import { readTextFile, writeTextFile } from '@tauri-apps/plugin-fs';
|
import { readTextFile, writeTextFile } from '@tauri-apps/plugin-fs';
|
||||||
import { invoke, invoke_nopopup } from './invoke';
|
import { invoke, invoke_nopopup } from './invoke';
|
||||||
import { Dirs, Feature, Game, Package, Profile, ProfileMeta } from './types';
|
import { Dirs, Feature, Game, Package, Profile, ProfileMeta } from './types';
|
||||||
import { changePrimaryColor, hasFeature, pkgKey } from './util';
|
import {
|
||||||
|
changePrimaryColor,
|
||||||
|
hasFeature,
|
||||||
|
pkgKey,
|
||||||
|
shouldPreferDark,
|
||||||
|
} from './util';
|
||||||
|
|
||||||
type InstallStatus = {
|
type InstallStatus = {
|
||||||
pkg: string;
|
pkg: string;
|
||||||
@ -356,6 +361,7 @@ export const useClientStore = defineStore('client', () => {
|
|||||||
const offlineMode = ref(false);
|
const offlineMode = ref(false);
|
||||||
const enableAutoupdates = ref(true);
|
const enableAutoupdates = ref(true);
|
||||||
const verbose = ref(false);
|
const verbose = ref(false);
|
||||||
|
const theme: Ref<'light' | 'dark' | 'system'> = ref('system');
|
||||||
|
|
||||||
const scaleValue = (value: ScaleType) =>
|
const scaleValue = (value: ScaleType) =>
|
||||||
value === 's' ? 1 : value === 'm' ? 1.25 : value === 'l' ? 1.5 : 2;
|
value === 's' ? 1 : value === 'm' ? 1.25 : value === 'l' ? 1.5 : 2;
|
||||||
@ -406,6 +412,11 @@ export const useClientStore = defineStore('client', () => {
|
|||||||
if (input.scaleFactor) {
|
if (input.scaleFactor) {
|
||||||
await setScaleFactor(input.scaleFactor);
|
await setScaleFactor(input.scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (input.theme) {
|
||||||
|
theme.value = input.theme;
|
||||||
|
}
|
||||||
|
await setTheme(theme.value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Error reading client options: ${e}`);
|
console.error(`Error reading client options: ${e}`);
|
||||||
}
|
}
|
||||||
@ -436,6 +447,7 @@ export const useClientStore = defineStore('client', () => {
|
|||||||
w: Math.floor(size.width),
|
w: Math.floor(size.width),
|
||||||
h: Math.floor(size.height),
|
h: Math.floor(size.height),
|
||||||
},
|
},
|
||||||
|
theme: theme.value,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -468,6 +480,21 @@ export const useClientStore = defineStore('client', () => {
|
|||||||
await invoke('set_global_config', { field: 'verbose', value });
|
await invoke('set_global_config', { field: 'verbose', value });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setTheme = async (value: 'light' | 'dark' | 'system') => {
|
||||||
|
if (value === 'dark') {
|
||||||
|
document.documentElement.classList.add('use-dark-mode');
|
||||||
|
} else if (value === 'light') {
|
||||||
|
document.documentElement.classList.remove('use-dark-mode');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.toggle(
|
||||||
|
'use-dark-mode',
|
||||||
|
shouldPreferDark()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
theme.value = value;
|
||||||
|
await save();
|
||||||
|
};
|
||||||
|
|
||||||
getCurrentWindow().onResized(async ({ payload }) => {
|
getCurrentWindow().onResized(async ({ payload }) => {
|
||||||
// For whatever reason this is 0 when minimized
|
// For whatever reason this is 0 when minimized
|
||||||
if (payload.width > 0) {
|
if (payload.width > 0) {
|
||||||
@ -480,6 +507,7 @@ export const useClientStore = defineStore('client', () => {
|
|||||||
offlineMode,
|
offlineMode,
|
||||||
enableAutoupdates,
|
enableAutoupdates,
|
||||||
verbose,
|
verbose,
|
||||||
|
theme,
|
||||||
timeout,
|
timeout,
|
||||||
scaleModel,
|
scaleModel,
|
||||||
load,
|
load,
|
||||||
@ -488,5 +516,6 @@ export const useClientStore = defineStore('client', () => {
|
|||||||
setOfflineMode,
|
setOfflineMode,
|
||||||
setAutoupdates,
|
setAutoupdates,
|
||||||
setVerbose,
|
setVerbose,
|
||||||
|
setTheme,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -59,3 +59,7 @@ export const hasFeature = (pkg: Package | undefined, feature: Feature) => {
|
|||||||
export const messageSplit = (message: any) => {
|
export const messageSplit = (message: any) => {
|
||||||
return message.message?.split('\n');
|
return message.message?.split('\n');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const shouldPreferDark = () => {
|
||||||
|
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user