forked from akanyan/STARTLINER
219 lines
6.1 KiB
TypeScript
219 lines
6.1 KiB
TypeScript
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 { invoke } from './invoke';
|
|
import { Dirs, Game, Package, Profile, ProfileMeta } from './types';
|
|
import { changePrimaryColor, pkgKey } from './util';
|
|
|
|
type InstallStatus = {
|
|
pkg: string;
|
|
};
|
|
|
|
export const useGeneralStore = defineStore('general', () => {
|
|
const dirs: Ref<Dirs | null> = ref(null);
|
|
|
|
const configDir = computed(() => {
|
|
if (dirs.value === null) {
|
|
throw new Error('Invalid directory access');
|
|
}
|
|
return dirs.value.config_dir;
|
|
});
|
|
const dataDir = computed(() => {
|
|
if (dirs.value === null) {
|
|
throw new Error('Invalid directory access');
|
|
}
|
|
return dirs.value.data_dir;
|
|
});
|
|
const cacheDir = computed(() => {
|
|
if (dirs.value === null) {
|
|
throw new Error('Invalid directory access');
|
|
}
|
|
return dirs.value.cache_dir;
|
|
});
|
|
|
|
return { dirs, configDir, dataDir, cacheDir };
|
|
});
|
|
|
|
export const usePkgStore = defineStore('pkg', {
|
|
state: (): { pkg: { [key: string]: Package } } => {
|
|
return {
|
|
pkg: {},
|
|
};
|
|
},
|
|
getters: {
|
|
fromDepString: (state) => (str: string) => state.pkg[str] ?? null,
|
|
fromName: (state) => (namespace: string, name: string) =>
|
|
state.pkg[`${namespace}-${name}`] ?? null,
|
|
all: (state) => Object.values(state),
|
|
allLocal: (state) => Object.values(state.pkg).filter((p) => p.loc),
|
|
allRemote: (state) => Object.values(state.pkg).filter((p) => p.rmt),
|
|
},
|
|
actions: {
|
|
setupListeners() {
|
|
listen<InstallStatus>('install-start', async (ev) => {
|
|
const key = ev.payload.pkg;
|
|
await this.reload(key);
|
|
this.pkg[key].js.busy = true;
|
|
});
|
|
|
|
listen<InstallStatus>('install-end', async (ev) => {
|
|
const key = ev.payload.pkg;
|
|
await this.reload(key);
|
|
this.pkg[key].js.busy = false;
|
|
});
|
|
},
|
|
|
|
async reloadAll() {
|
|
await invoke('reload_all_packages');
|
|
const data = (await invoke('get_all_packages')) as {
|
|
[key: string]: Package;
|
|
};
|
|
|
|
for (const [k, v] of Object.entries(data)) {
|
|
this.reloadWith(k, v);
|
|
}
|
|
},
|
|
|
|
async reload(pkgOrKey: string | Package) {
|
|
const key =
|
|
typeof pkgOrKey === 'string' ? pkgOrKey : pkgKey(pkgOrKey);
|
|
const pkg: Package = await invoke('get_package', {
|
|
key,
|
|
});
|
|
this.reloadWith(key, pkg);
|
|
},
|
|
|
|
async reloadWith(key: string, pkg: Package) {
|
|
if (this.pkg[key] === undefined) {
|
|
this.pkg[key] = { js: { busy: false } } as Package;
|
|
} else {
|
|
this.pkg[key].loc = null;
|
|
this.pkg[key].rmt = null;
|
|
}
|
|
Object.assign(this.pkg[key], pkg);
|
|
},
|
|
|
|
async fetch() {
|
|
await invoke('fetch_listings');
|
|
await this.reloadAll();
|
|
},
|
|
},
|
|
});
|
|
|
|
export const usePrfStore = defineStore('prf', () => {
|
|
const current: Ref<Profile | null> = ref(null);
|
|
const list: Ref<ProfileMeta[]> = ref([]);
|
|
|
|
const isPkgEnabled = (pkg: Package | undefined) =>
|
|
computed(
|
|
() =>
|
|
pkg !== undefined &&
|
|
current.value !== null &&
|
|
current.value?.mods.includes(pkgKey(pkg))
|
|
);
|
|
|
|
const reload = async () => {
|
|
const p = (await invoke('get_current_profile')) as any;
|
|
if (p != null && 'OngekiProfile' in p) {
|
|
current.value = { ...p.OngekiProfile, game: 'ongeki' };
|
|
} else {
|
|
current.value = null;
|
|
}
|
|
if (current.value !== null) {
|
|
changePrimaryColor(current.value.game);
|
|
} else {
|
|
changePrimaryColor(null);
|
|
}
|
|
};
|
|
|
|
const create = async (game: Game) => {
|
|
try {
|
|
await invoke('init_profile', {
|
|
game,
|
|
name: 'new-profile',
|
|
});
|
|
await reload();
|
|
await reloadList();
|
|
} catch (e) {
|
|
current.value = null;
|
|
}
|
|
|
|
if (current.value !== null) {
|
|
const pkgs = usePkgStore();
|
|
pkgs.reloadAll();
|
|
}
|
|
};
|
|
|
|
const rename = async (profile: ProfileMeta, name: string) => {
|
|
await invoke('rename_profile', {
|
|
profile,
|
|
name,
|
|
});
|
|
|
|
if (
|
|
current.value?.game === profile.game &&
|
|
current.value.name === profile.name
|
|
) {
|
|
current.value.name = name;
|
|
}
|
|
|
|
await reloadList();
|
|
};
|
|
|
|
const switchTo = async (game: Game, name: string) => {
|
|
await invoke('load_profile', { game, name });
|
|
await reload();
|
|
if (current.value !== null) {
|
|
const pkgs = usePkgStore();
|
|
pkgs.reloadAll();
|
|
}
|
|
};
|
|
|
|
const reloadList = async () => {
|
|
list.value = (await invoke('list_profiles')) as ProfileMeta[];
|
|
};
|
|
|
|
const togglePkg = async (pkg: Package | undefined, enable: boolean) => {
|
|
if (pkg === undefined) {
|
|
return;
|
|
}
|
|
await invoke('toggle_package', { key: pkgKey(pkg), enable });
|
|
await reload();
|
|
};
|
|
|
|
const generalStore = useGeneralStore();
|
|
|
|
const configDir = computed(async () => {
|
|
return await path.join(
|
|
generalStore.configDir,
|
|
`profile-${current.value?.game}-${current.value?.name}`
|
|
);
|
|
});
|
|
|
|
listen<InstallStatus>('install-end', async () => {
|
|
await reload();
|
|
});
|
|
|
|
watchEffect(async () => {
|
|
if (current.value !== null) {
|
|
await invoke('save_current_profile', {
|
|
profile: { OngekiProfile: current.value },
|
|
});
|
|
}
|
|
});
|
|
|
|
return {
|
|
current,
|
|
list,
|
|
isPkgEnabled,
|
|
reload,
|
|
create,
|
|
rename,
|
|
switchTo,
|
|
reloadList,
|
|
togglePkg,
|
|
configDir,
|
|
};
|
|
});
|