diff --git a/CHANGELOG.md b/CHANGELOG.md index db8860b..e6c1f67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.0 + +- Added a light/dark theme switcher + ## 0.8.1 - Hotfixed the program failing to launch if the data dir hadn't already been created diff --git a/rust/tauri.conf.json b/rust/tauri.conf.json index 41ddd25..200e8b7 100644 --- a/rust/tauri.conf.json +++ b/rust/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "STARTLINER", - "version": "0.8.1", + "version": "0.9.0", "identifier": "zip.patafour.startliner", "build": { "beforeDevCommand": "bun run dev", diff --git a/src/components/App.vue b/src/components/App.vue index bdd1390..927cda4 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -28,7 +28,9 @@ import { usePrfStore, } from '../stores'; 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 prf = usePrfStore(); diff --git a/src/components/options/Startliner.vue b/src/components/options/Startliner.vue index a38f5d5..645c256 100644 --- a/src/components/options/Startliner.vue +++ b/src/components/options/Startliner.vue @@ -34,6 +34,15 @@ const verboseModel = computed({ await client.setVerbose(value); }, }); + +const themeModel = computed({ + get() { + return client.theme; + }, + async set(value: 'light' | 'dark' | 'system') { + await client.setTheme(value); + }, +}); diff --git a/src/main.ts b/src/main.ts index 48421ff..9b1da04 100644 --- a/src/main.ts +++ b/src/main.ts @@ -17,6 +17,9 @@ app.use(pinia); app.use(PrimeVue, { theme: { preset: Preset, + options: { + darkModeSelector: '.use-dark-mode', + }, }, }); app.use(ConfirmationService); diff --git a/src/stores.ts b/src/stores.ts index 871ae86..97951b8 100644 --- a/src/stores.ts +++ b/src/stores.ts @@ -6,7 +6,12 @@ import { PhysicalSize, getCurrentWindow } from '@tauri-apps/api/window'; import { readTextFile, writeTextFile } from '@tauri-apps/plugin-fs'; import { invoke, invoke_nopopup } from './invoke'; import { Dirs, Feature, Game, Package, Profile, ProfileMeta } from './types'; -import { changePrimaryColor, hasFeature, pkgKey } from './util'; +import { + changePrimaryColor, + hasFeature, + pkgKey, + shouldPreferDark, +} from './util'; type InstallStatus = { pkg: string; @@ -356,6 +361,7 @@ export const useClientStore = defineStore('client', () => { const offlineMode = ref(false); const enableAutoupdates = ref(true); const verbose = ref(false); + const theme: Ref<'light' | 'dark' | 'system'> = ref('system'); const scaleValue = (value: ScaleType) => value === 's' ? 1 : value === 'm' ? 1.25 : value === 'l' ? 1.5 : 2; @@ -406,6 +412,11 @@ export const useClientStore = defineStore('client', () => { if (input.scaleFactor) { await setScaleFactor(input.scaleFactor); } + + if (input.theme) { + theme.value = input.theme; + } + await setTheme(theme.value); } catch (e) { console.error(`Error reading client options: ${e}`); } @@ -436,6 +447,7 @@ export const useClientStore = defineStore('client', () => { w: Math.floor(size.width), 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 }); }; + 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 }) => { // For whatever reason this is 0 when minimized if (payload.width > 0) { @@ -480,6 +507,7 @@ export const useClientStore = defineStore('client', () => { offlineMode, enableAutoupdates, verbose, + theme, timeout, scaleModel, load, @@ -488,5 +516,6 @@ export const useClientStore = defineStore('client', () => { setOfflineMode, setAutoupdates, setVerbose, + setTheme, }; }); diff --git a/src/util.ts b/src/util.ts index d01cfb3..c0f8ca4 100644 --- a/src/util.ts +++ b/src/util.ts @@ -59,3 +59,7 @@ export const hasFeature = (pkg: Package | undefined, feature: Feature) => { export const messageSplit = (message: any) => { return message.message?.split('\n'); }; + +export const shouldPreferDark = () => { + return window.matchMedia('(prefers-color-scheme: dark)').matches; +};