Async downloader, better Proton support (#183)

* feat: async downloader + other fixes

* feat: windows command parsing + use library path for install path

* feat: better proton support

* feat: style fixes and store button now uses in-app

* feat: emulator rename + umu emulator fix

* feat: bring process creation inline with docs

* fix: clippy
This commit is contained in:
DecDuck
2026-02-06 23:24:14 +11:00
committed by GitHub
parent b71809c041
commit 01335dadaf
45 changed files with 1453 additions and 381 deletions
+26 -21
View File
@@ -35,15 +35,18 @@
@resume="() => resumeDownload()"
:status="status"
/>
<a
:href="remoteUrl"
target="_blank"
type="button"
<NuxtLink
class="transition-transform duration-300 hover:scale-105 active:scale-95 inline-flex items-center rounded-md bg-zinc-800/50 px-6 font-semibold text-white shadow-xl backdrop-blur-sm hover:bg-zinc-800/80 uppercase font-display"
:to="{
path: '/store',
query: {
gameId: game.id,
},
}"
>
<BuildingStorefrontIcon class="mr-2 size-5" aria-hidden="true" />
Store
</a>
</NuxtLink>
</div>
</div>
@@ -171,7 +174,11 @@
</div>
<div class="space-y-6">
<div v-if="versionOptions && versionOptions.length > 0 && currentVersionOption">
<div
v-if="
versionOptions && versionOptions.length > 0 && currentVersionOption
"
>
<Listbox as="div" v-model="installVersionIndex">
<ListboxLabel class="block text-sm/6 font-medium text-zinc-100"
>Version</ListboxLabel
@@ -188,7 +195,7 @@
on
{{ currentVersionOption.platform }} ({{
formatKilobytes(
currentVersionOption.size / 1024
currentVersionOption.size.installSize / 1024,
)
}}B)</span
>
@@ -233,7 +240,8 @@
>{{ version.displayName || version.versionPath }} on
{{ version.platform }} ({{
formatKilobytes(
versionOptions[installVersionIndex].size / 1024
versionOptions[installVersionIndex].size
.installSize / 1024,
)
}}B)</span
>
@@ -314,8 +322,7 @@
</div>
<ul role="list" class="mt-2 divide-y divide-white/5">
<li
v-for="content in currentVersionOption
.requiredContent"
v-for="content in currentVersionOption.requiredContent"
:key="content.versionId"
:class="[
!installDepsDisabled[content.versionId]
@@ -353,7 +360,7 @@
<p
class="inline-flex items-center gap-x-1 text-xs/5 text-gray-400"
>
{{ formatKilobytes(content.size / 1024) }}B
{{ formatKilobytes(content.size.installSize / 1024) }}B
<ServerIcon class="size-3" />
</p>
</div>
@@ -566,10 +573,6 @@ const id = route.params.id.toString();
const { game: rawGame, status } = await useGame(id);
const game = ref(rawGame);
const remoteUrl: string = await invoke("gen_drop_url", {
path: `/store/${game.value.id}`,
});
const bannerUrl = await useObject(game.value.mBannerObjectId);
// Get all available images
@@ -577,7 +580,7 @@ const mediaUrls = await Promise.all(
game.value.mImageCarouselObjectIds.map(async (v) => {
const src = await useObject(v);
return src;
})
}),
);
const htmlDescription = micromark(game.value.mDescription);
@@ -611,7 +614,9 @@ const installVersionIndex = ref(0);
const installDir = ref(0);
const installDepsDisabled = ref<{ [key: string]: boolean }>({});
const currentVersionOption = computed(() => versionOptions.value?.[installVersionIndex.value]);
const currentVersionOption = computed(
() => versionOptions.value?.[installVersionIndex.value],
);
async function install() {
try {
if (!versionOptions.value) throw new Error("Versions have not been loaded");
@@ -661,7 +666,7 @@ async function launch() {
try {
const fetchedLaunchOptions = await invoke<Array<{ name: string }>>(
"get_launch_options",
{ id: game.value.id }
{ id: game.value.id },
);
if (fetchedLaunchOptions.length == 1) {
await launchIndex(0);
@@ -676,7 +681,7 @@ async function launch() {
description: `Drop failed to launch "${game.value.mName}": ${e}`,
buttonText: "Close",
},
(e, c) => c()
(e, c) => c(),
);
console.error(e);
}
@@ -707,7 +712,7 @@ async function launchIndex(index: number) {
description: `Drop failed to launch "${game.value.mName}": ${e}`,
buttonText: "Close",
},
(e, c) => c()
(e, c) => c(),
);
}
}
@@ -731,7 +736,7 @@ async function kill() {
description: `Drop failed to stop "${game.value.mName}": ${e}`,
buttonText: "Close",
},
(e, c) => c()
(e, c) => c(),
);
console.error(e);
}