Files
drop-app/main/composables/game.ts
DecDuck 5ad005161f
Some checks failed
publish / publish-tauri (, ubuntu-22.04) (release) Failing after 14m38s
publish / publish-tauri (, windows-latest) (release) Has been cancelled
publish / publish-tauri (--target aarch64-apple-darwin, macos-14) (release) Has been cancelled
publish / publish-tauri (--target aarch64-unknown-linux-gnu, ubuntu-22.04-arm) (release) Has been cancelled
publish / publish-tauri (--target x86_64-apple-darwin, macos-14) (release) Has been cancelled
Depot API & executor launch (#173)
* feat: depot api downloads

* feat: frontend fixes and experimental webview store

* feat: sync downloader

* feat: cleanup and fixes

* feat: encrypted database and fixed resuming

* feat: launch option selector

* fix: autostart when no options

* fix: clippy

* fix: clippy x2

* feat: executor launch

* feat: executor launch

* feat: not installed error handling

* feat: better offline handling

* feat: dependency popup

* fix: cancelation and resuming issues

* feat: dedup by platform

* feat: new ui for additional components and fix dl manager clog

* feat: auto-queue dependencies

* feat: depot scanning and ranking

* feat: new library fetching stack

* In-app store page (Windows + macOS) (#176)

* feat: async store loading

* feat: fix overscroll behaviour

* fix: query params in server protocol

* fix: clippy
2026-01-20 11:40:48 +11:00

94 lines
2.6 KiB
TypeScript

import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import type { Game, GameStatus, GameStatusEnum, GameVersion } from "~/types";
const gameRegistry: { [key: string]: { game: Game; version?: GameVersion } } =
{};
const gameStatusRegistry: { [key: string]: Ref<GameStatus> } = {};
type OptionGameStatus = { [key in GameStatusEnum]: { version_name?: string } };
export type SerializedGameStatus = [
{ type: GameStatusEnum },
OptionGameStatus | null
];
export const parseStatus = (status: SerializedGameStatus): GameStatus => {
if (status[0]) {
return {
type: status[0].type,
};
} else if (status[1]) {
const [[gameStatus, options]] = Object.entries(status[1]);
return {
type: gameStatus as GameStatusEnum,
...options,
};
} else {
throw new Error("No game status");
}
};
export const useGame = async (gameId: string) => {
if (!gameRegistry[gameId]) {
const data: {
game: Game;
status: SerializedGameStatus;
version?: GameVersion;
} = await invoke("fetch_game", {
gameId,
});
gameRegistry[gameId] = { game: data.game, version: data.version };
if (!gameStatusRegistry[gameId]) {
gameStatusRegistry[gameId] = ref(parseStatus(data.status));
listen(`update_game/${gameId}`, (event) => {
const payload: {
status: SerializedGameStatus;
version?: GameVersion;
} = event.payload as any;
gameStatusRegistry[gameId].value = parseStatus(payload.status);
/**
* I am not super happy about this.
*
* This will mean that we will still have a version assigned if we have a game installed then uninstall it.
* It is necessary because a flag to check if we should overwrite seems excessive, and this function gets called
* on transient state updates.
*/
if (payload.version) {
gameRegistry[gameId].version = payload.version;
}
});
}
}
const game = gameRegistry[gameId];
const status = gameStatusRegistry[gameId];
return { ...game, status };
};
export type FrontendGameConfiguration = {
launchString: string;
};
export type LaunchResult =
| { result: "Success" }
| { result: "InstallRequired"; data: [string, string] };
export type VersionOption = {
versionId: string;
displayName?: string;
versionPath: string;
platform: string;
size: number;
requiredContent: Array<{
gameId: string;
versionId: string;
name: string;
iconObjectId: string;
shortDescription: string;
size: number;
}>;
};