feat: ui scaling, update all

This commit is contained in:
2025-04-04 14:37:16 +00:00
parent 536f289cfe
commit 8c3f9762a4
15 changed files with 429 additions and 176 deletions

View File

@ -2,6 +2,8 @@ import { Ref, computed, ref, watchEffect } from 'vue';
import { defineStore } from 'pinia';
import { listen } from '@tauri-apps/api/event';
import * as path from '@tauri-apps/api/path';
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';
@ -102,6 +104,10 @@ export const usePkgStore = defineStore('pkg', {
),
byFeature: (state) => (feature: Feature) =>
Object.values(state.pkg).filter((p) => hasFeature(p, feature)),
hasAvailableUpdates: (state) =>
Object.values(state.pkg).some(
(p) => p.loc && (p.rmt?.version ?? 0) > p.loc.version
),
},
actions: {
setupListeners() {
@ -170,6 +176,36 @@ export const usePkgStore = defineStore('pkg', {
}
await this.reloadAll();
},
async install(pkg: Package | undefined) {
if (pkg === undefined) {
return;
}
try {
await invoke('install_package', {
key: pkgKey(pkg),
force: true,
});
} catch (err) {
console.error(err);
if (pkg !== undefined) {
pkg.js.busy = false;
}
}
//if (rv === 'Deferred') { /* download progress */ }
},
async updateAll() {
const list = [];
for (const pkg of this.allLocal) {
if (pkg.rmt && pkg.rmt.version > pkg.loc!.version) {
list.push(this.install(pkg));
}
}
await Promise.all(list);
},
},
});
@ -295,3 +331,116 @@ export const usePrfStore = defineStore('prf', () => {
configDir,
};
});
export const useClientStore = defineStore('client', () => {
type ScaleType = 's' | 'm' | 'l' | 'xl';
const scaleFactor: Ref<ScaleType> = ref('s');
const timeout: Ref<NodeJS.Timeout | null> = ref(null);
const offlineMode = ref(true);
const scaleValue = (value: ScaleType) =>
value === 's' ? 1 : value === 'm' ? 1.25 : value === 'l' ? 1.5 : 2;
const setScaleFactor = async (value: ScaleType) => {
scaleFactor.value = value;
const window = getCurrentWindow();
const w = Math.floor(scaleValue(value) * 760);
const h = Math.floor(scaleValue(value) * 480);
let size = await window.innerSize();
window.setMinSize(new PhysicalSize(w, h));
window.setSize(
new PhysicalSize(Math.max(w, size.width), Math.max(h, size.height))
);
};
const scaleModel = computed({
get() {
return scaleFactor;
},
async set(value: ScaleType) {
await setScaleFactor(value);
await save();
},
});
const load = async () => {
const generalStore = useGeneralStore();
try {
const input = JSON.parse(
await readTextFile(
await path.join(
generalStore.configDir,
'client-options.json'
)
)
);
if (input.windowSize) {
getCurrentWindow().setSize(
new PhysicalSize(input.windowSize.w, input.windowSize.h)
);
}
if (input.scaleFactor) {
await setScaleFactor(input.scaleFactor);
}
offlineMode.value = await invoke('is_offline');
} catch (e) {
console.error(`Error reading client options: ${e}`);
}
};
const save = async () => {
const generalStore = useGeneralStore();
const w = getCurrentWindow();
const size = await w.innerSize();
await writeTextFile(
await path.join(generalStore.configDir, 'client-options.json'),
JSON.stringify({
scaleFactor: scaleFactor.value,
windowSize: {
w: Math.floor(size.width),
h: Math.floor(size.height),
},
})
);
};
const queueSave = async () => {
if (timeout.value !== null) {
clearTimeout(timeout.value);
}
timeout.value = setTimeout(async () => {
timeout.value = null;
await save();
}, 1000);
};
const setOfflineMode = async (value: boolean) => {
offlineMode.value = value;
await invoke('set_offline', { value });
};
getCurrentWindow().onResized(async ({ payload }) => {
// For whatever reason this is 0 when minimized
if (payload.width > 0) {
await queueSave();
}
});
return {
scaleFactor,
offlineMode,
timeout,
scaleModel,
load,
save,
queueSave,
setOfflineMode,
};
});