fix: misc cleanup

This commit is contained in:
2025-04-23 14:24:35 +00:00
parent 8b2c1a04ee
commit f26d83f291
11 changed files with 89 additions and 59 deletions

View File

@ -190,12 +190,16 @@ pub async fn get_all_packages(state: State<'_, Mutex<AppData>>) -> Result<HashMa
#[tauri::command] #[tauri::command]
pub async fn get_game_packages(state: State<'_, Mutex<AppData>>, game: Game) -> Result<Vec<PkgKey>, ()> { pub async fn get_game_packages(state: State<'_, Mutex<AppData>>, game: Option<Game>) -> Result<Vec<PkgKey>, ()> {
log::debug!("invoke: get_game_packages {game}"); log::debug!("invoke: get_game_packages {game:?}");
let appd = state.lock().await; let appd = state.lock().await;
Ok(appd.pkgs.get_game_list(game)) if let Some(game) = game {
Ok(appd.pkgs.get_game_list(game))
} else {
Ok(Vec::new())
}
} }
#[tauri::command] #[tauri::command]
@ -437,6 +441,26 @@ pub async fn import_profile(path: PathBuf) -> Result<(), String> {
Profile::import(path).map_err(|e| e.to_string()) Profile::import(path).map_err(|e| e.to_string())
} }
#[tauri::command]
pub async fn clear_cache(state: State<'_, Mutex<AppData>>) -> Result<(), String> {
log::debug!("invoke: clear_cache");
let appd = state.lock().await;
if let Some(p) = &appd.profile {
let dir = p.data_dir().join("mu3-mods-cache");
let path = dir.join("data_cache.bin");
if path.exists() {
std::fs::remove_file(path).map_err(|e| e.to_string())?;
}
let path = dir.join("data_fumen_analysis_cache.bin");
if path.exists() {
std::fs::remove_file(path).map_err(|e| e.to_string())?;
}
}
Ok(())
}
#[tauri::command] #[tauri::command]
pub async fn list_platform_capabilities() -> Result<Vec<String>, ()> { pub async fn list_platform_capabilities() -> Result<Vec<String>, ()> {
log::debug!("invoke: list_platform_capabilities"); log::debug!("invoke: list_platform_capabilities");

View File

@ -207,6 +207,7 @@ pub async fn run(_args: Vec<String>) {
cmd::create_shortcut, cmd::create_shortcut,
cmd::export_profile, cmd::export_profile,
cmd::import_profile, cmd::import_profile,
cmd::clear_cache,
cmd::get_global_config, cmd::get_global_config,
cmd::set_global_config, cmd::set_global_config,

View File

@ -56,11 +56,6 @@ listen<undefined>('update-end', (_) => {
}); });
onMounted(async () => { onMounted(async () => {
invoke('list_directories').then((d) => {
general.dirs = d as Dirs;
client.load();
});
const fetch_promise = pkg.fetch(true); const fetch_promise = pkg.fetch(true);
await Promise.all([prf.reloadList(), prf.reload()]); await Promise.all([prf.reloadList(), prf.reload()]);
@ -231,8 +226,9 @@ listen<DownloadingStatus>('download-progress', (event) => {
><div class="pi pi-ticket"></div ><div class="pi pi-ticket"></div
></Tab> ></Tab>
<Tab <Tab
v-if="pkg.networkStatus === 'online'" :disabled="
:disabled="isProfileDisabled" isProfileDisabled || pkg.networkStatus !== 'online'
"
value="rmt" value="rmt"
><div class="pi pi-download"></div ><div class="pi pi-download"></div
></Tab> ></Tab>
@ -304,19 +300,19 @@ listen<DownloadingStatus>('download-progress', (event) => {
</TabList> </TabList>
</div> </div>
<TabPanels class="w-full grow mt-[3rem]"> <TabPanels class="w-full grow mt-[3rem]">
<TabPanel value="loc"> <TabPanel value="loc" v-if="!isProfileDisabled">
<ModList :search="pkgSearchTerm" /> <ModList :search="pkgSearchTerm" />
</TabPanel> </TabPanel>
<TabPanel value="rmt"> <TabPanel value="rmt" v-if="!isProfileDisabled">
<ModStore :search="pkgSearchTerm" /> <ModStore :search="pkgSearchTerm" />
</TabPanel> </TabPanel>
<TabPanel value="cfg"> <TabPanel value="cfg" v-if="!isProfileDisabled">
<OptionList /> <OptionList />
</TabPanel> </TabPanel>
<TabPanel value="users"> <TabPanel value="users">
<ProfileList /> <ProfileList />
</TabPanel> </TabPanel>
<TabPanel value="patches"> <TabPanel value="patches" v-if="!isProfileDisabled">
<PatchList <PatchList
v-if=" v-if="
pkg.hasLocal('mempatcher-mempatcher') && pkg.hasLocal('mempatcher-mempatcher') &&

View File

@ -22,7 +22,7 @@ const empty = ref(false);
const gameSublist: Ref<string[]> = ref([]); const gameSublist: Ref<string[]> = ref([]);
invoke('get_game_packages', { invoke('get_game_packages', {
game: prf.current?.meta.game, game: prf.current?.meta.game ?? null,
}).then((list) => { }).then((list) => {
gameSublist.value = list as string[]; gameSublist.value = list as string[];
}); });
@ -55,6 +55,9 @@ const group = computed(() => {
const missing = computed(() => { const missing = computed(() => {
return prf.current?.data.mods.filter((m) => !pkgs.hasLocal(m)) ?? []; return prf.current?.data.mods.filter((m) => !pkgs.hasLocal(m)) ?? [];
}); });
const emptyVisible = ref(false);
setTimeout(() => (emptyVisible.value = true), 500);
</script> </script>
<template> <template>
@ -84,5 +87,7 @@ const missing = computed(() => {
<Fieldset v-for="(namespace, key) in group" :legend="key.toString()"> <Fieldset v-for="(namespace, key) in group" :legend="key.toString()">
<ModListEntry v-for="p in namespace" :pkg="p" /> <ModListEntry v-for="p in namespace" :pkg="p" />
</Fieldset> </Fieldset>
<div v-if="empty === true" class="text-3xl fadein"></div> <div v-if="empty === true && emptyVisible === true" class="text-3xl fadein">
</div>
</template> </template>

View File

@ -23,7 +23,7 @@ const props = defineProps({
const gameSublist: Ref<string[]> = ref([]); const gameSublist: Ref<string[]> = ref([]);
invoke('get_game_packages', { invoke('get_game_packages', {
game: prf.current?.meta.game, game: prf.current?.meta.game ?? null,
}).then((list) => { }).then((list) => {
gameSublist.value = list as string[]; gameSublist.value = list as string[];
}); });
@ -46,10 +46,10 @@ const list = () => {
}; };
const shouldShowRecommended = computed(() => { const shouldShowRecommended = computed(() => {
if (prf.current!.meta.game === 'ongeki') { if (prf.current?.meta.game === 'ongeki') {
return !pkgs.allLocal.some((p) => pkgKey(p) === 'segatools-mu3hook'); return !pkgs.allLocal.some((p) => pkgKey(p) === 'segatools-mu3hook');
} }
if (prf.current!.meta.game === 'chunithm') { if (prf.current?.meta.game === 'chunithm') {
return ( return (
!pkgs.allLocal.some((p) => pkgKey(p) === 'segatools-chusanhook') || !pkgs.allLocal.some((p) => pkgKey(p) === 'segatools-chusanhook') ||
!pkgs.allLocal.some((p) => pkgKey(p) === 'mempatcher-mempatcher') !pkgs.allLocal.some((p) => pkgKey(p) === 'mempatcher-mempatcher')
@ -58,21 +58,21 @@ const shouldShowRecommended = computed(() => {
return false; return false;
}); });
const getRecommendedTooltip = () => { const recommendedTooltip = computed(() => {
if (prf.current!.meta.game === 'ongeki') { if (prf.current?.meta.game === 'ongeki') {
return 'segatools-mu3hook'; return 'segatools-mu3hook';
} }
if (prf.current!.meta.game === 'chunithm') { if (prf.current?.meta.game === 'chunithm') {
return 'segatools-chusanhook + mempatcher'; return 'segatools-chusanhook + mempatcher';
} }
return ''; return '';
}; });
const installRecommended = () => { const installRecommended = () => {
if (prf.current!.meta.game === 'ongeki') { if (prf.current?.meta.game === 'ongeki') {
pkgs.installFromKey('segatools-mu3hook'); pkgs.installFromKey('segatools-mu3hook');
} }
if (prf.current!.meta.game === 'chunithm') { if (prf.current?.meta.game === 'chunithm') {
pkgs.installFromKey('segatools-chusanhook'); pkgs.installFromKey('segatools-chusanhook');
pkgs.installFromKey('mempatcher-mempatcher'); pkgs.installFromKey('mempatcher-mempatcher');
} }
@ -120,7 +120,7 @@ const installRecommended = () => {
<Button <Button
v-if="shouldShowRecommended" v-if="shouldShowRecommended"
:label="t('store.installRecommended')" :label="t('store.installRecommended')"
v-tooltip="getRecommendedTooltip" v-tooltip="recommendedTooltip"
icon="pi pi-plus" icon="pi pi-plus"
class="mb-3" class="mb-3"
@click="installRecommended" @click="installRecommended"

View File

@ -61,7 +61,7 @@ prf.reload();
<MiscOptions /> <MiscOptions />
<OptionCategory <OptionCategory
title="Extensions" title="Extensions"
v-if="prf.current!.meta.game === 'chunithm'" v-if="prf.current?.meta.game === 'chunithm'"
> >
<OptionRow :title="t('cfg.extensions.saekawa')"> <OptionRow :title="t('cfg.extensions.saekawa')">
<FileEditor <FileEditor
@ -72,7 +72,7 @@ prf.reload();
></OptionCategory> ></OptionCategory>
<OptionCategory <OptionCategory
:title="t('cfg.extensions.title')" :title="t('cfg.extensions.title')"
v-if="prf.current!.meta.game === 'ongeki'" v-if="prf.current?.meta.game === 'ongeki'"
> >
<OptionRow :title="t('cfg.extensions.inohara')"> <OptionRow :title="t('cfg.extensions.inohara')">
<FileEditor <FileEditor

View File

@ -30,7 +30,7 @@ const exportTemplate = async () => {
files: fl, files: fl,
}); });
await invoke('open_file', { await invoke('open_file', {
path: await path.join(general.configDir, 'exports'), path: await path.join(await general.configDir, 'exports'),
}); });
}; };

View File

@ -137,7 +137,7 @@ const menuItems = computed(() => {
{ {
label: t('start.button.cache'), label: t('start.button.cache'),
icon: 'pi pi-trash', icon: 'pi pi-trash',
command: async () => {}, command: async () => await invoke('clear_cache'),
}, },
]; ];
} }

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { Ref, computed, ref } from 'vue'; import { Ref, computed, onMounted, ref } from 'vue';
import InputNumber from 'primevue/inputnumber'; import InputNumber from 'primevue/inputnumber';
import Select from 'primevue/select'; import Select from 'primevue/select';
import SelectButton from 'primevue/selectbutton'; import SelectButton from 'primevue/selectbutton';
@ -67,10 +67,12 @@ const loadDisplays = () => {
loadDisplays(); loadDisplays();
const game = prf.current!.meta.game; const game = computed(() => prf.current!.meta.game);
const isVertical = game === 'ongeki'; const isVertical = computed(() => prf.current!.meta.game === 'ongeki');
const adjustableRez = game === 'ongeki'; const adjustableRez = computed(() => prf.current!.meta.game === 'ongeki');
const canSkipPrimarySwitch = game === 'ongeki'; const canSkipPrimarySwitch = computed(
() => prf.current!.meta.game === 'ongeki'
);
</script> </script>
<template> <template>

View File

@ -35,8 +35,6 @@ const names = computed(() => {
io: 'chuniio', io: 'chuniio',
}; };
} }
case undefined:
throw new Error('Option tab without a profile');
} }
}); });
@ -59,14 +57,14 @@ const checkSegatoolsIni = async (target: string) => {
<template> <template>
<OptionCategory :title="t('cfg.segatools.general')"> <OptionCategory :title="t('cfg.segatools.general')">
<OptionRow <OptionRow
:title="names.exe" :title="names?.exe"
:tooltip="t('cfg.segatools.targetTooltip')" :tooltip="t('cfg.segatools.targetTooltip')"
> >
<FilePicker <FilePicker
:directory="false" :directory="false"
:promptname="names.exe" :promptname="names?.exe"
extension="exe" extension="exe"
:value="prf.current!.data.sgt.target" :value="prf.current?.data.sgt.target"
:callback=" :callback="
(value: string) => ( (value: string) => (
(prf.current!.data.sgt.target = value), (prf.current!.data.sgt.target = value),
@ -80,7 +78,7 @@ const checkSegatoolsIni = async (target: string) => {
<FilePicker <FilePicker
:directory="true" :directory="true"
placeholder="amfs" placeholder="amfs"
:value="prf.current!.data.sgt.amfs" :value="prf.current?.data.sgt.amfs"
:callback=" :callback="
(value: string) => (prf.current!.data.sgt.amfs = value) (value: string) => (prf.current!.data.sgt.amfs = value)
" "
@ -106,7 +104,7 @@ const checkSegatoolsIni = async (target: string) => {
></FilePicker> ></FilePicker>
</OptionRow> </OptionRow>
<OptionRow <OptionRow
:title="names.hook" :title="names?.hook"
:tooltip=" :tooltip="
t('cfg.segatools.installTooltip', { t('cfg.segatools.installTooltip', {
thing: t('cfg.segatools.hooks'), thing: t('cfg.segatools.hooks'),
@ -132,7 +130,7 @@ const checkSegatoolsIni = async (target: string) => {
></Select> ></Select>
</OptionRow> </OptionRow>
<OptionRow <OptionRow
:title="names.io" :title="names?.io"
:tooltip=" :tooltip="
t('cfg.segatools.installTooltip', { t('cfg.segatools.installTooltip', {
thing: t('cfg.segatools.ioModules'), thing: t('cfg.segatools.ioModules'),

View File

@ -32,23 +32,24 @@ export const useGeneralStore = defineStore('general', () => {
}, },
}); });
const configDir = computed(() => { const loadDirs = async () => {
if (dirs.value === null) { if (dirs.value === null) {
throw new Error('Invalid directory access'); const d = (await invoke('list_directories')) as Dirs;
dirs.value = d;
} }
return dirs.value.config_dir; };
const configDir = computed(async () => {
await loadDirs();
return dirs.value!.config_dir;
}); });
const dataDir = computed(() => { const dataDir = computed(async () => {
if (dirs.value === null) { await loadDirs();
throw new Error('Invalid directory access'); return dirs.value!.data_dir;
}
return dirs.value.data_dir;
}); });
const cacheDir = computed(() => { const cacheDir = computed(async () => {
if (dirs.value === null) { await loadDirs();
throw new Error('Invalid directory access'); return dirs.value!.cache_dir;
}
return dirs.value.cache_dir;
}); });
return { return {
@ -322,7 +323,7 @@ export const usePrfStore = defineStore('prf', () => {
const configDir = computed(async () => { const configDir = computed(async () => {
return await path.join( return await path.join(
generalStore.configDir, await generalStore.configDir,
`profile-${current.value?.meta.game}-${current.value?.meta.name}` `profile-${current.value?.meta.game}-${current.value?.meta.name}`
); );
}); });
@ -412,7 +413,7 @@ export const useClientStore = defineStore('client', () => {
const input = JSON.parse( const input = JSON.parse(
await readTextFile( await readTextFile(
await path.join( await path.join(
generalStore.configDir, await generalStore.configDir,
'client-options.json' 'client-options.json'
) )
) )
@ -464,7 +465,10 @@ export const useClientStore = defineStore('client', () => {
const size = await w.innerSize(); const size = await w.innerSize();
await writeTextFile( await writeTextFile(
await path.join(generalStore.configDir, 'client-options.json'), await path.join(
await generalStore.configDir,
'client-options.json'
),
JSON.stringify({ JSON.stringify({
scaleFactor: scaleFactor.value, scaleFactor: scaleFactor.value,
windowSize: { windowSize: {