refactor: hook based download

This commit is contained in:
Szedann 2025-07-24 13:52:09 +02:00
parent 4eb533d0e3
commit 766d3a24c4
3 changed files with 54 additions and 28 deletions

View file

@ -212,14 +212,8 @@ export type VersionType =
*/
"old_beta"
const ARGS_MAP = { 'core':'{"removeUser":["uuid"],"writeSettings":["setting"],"updateClusterById":["id","request"],"getScreenshots":["id"],"getClusters":[],"getWorlds":["id"],"getGameVersions":[],"getPackage":["provider","slug"],"getLoadersForVersion":["mc_version"],"getMultiplePackages":["provider","slugs"],"getPackageUser":["provider","slug"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getUsersFromAuthor":["provider","author"],"searchPackages":["provider","query"],"getUser":["uuid"],"getProfileOrDefault":["name"],"updateClusterProfile":["name","profile"],"getPackageVersions":["provider","slug","mc_versions","loaders","offset","limit"],"launchCluster":["id","uuid"],"setDefaultUser":["uuid"],"openMsaLogin":[],"getGlobalProfile":[],"getClusterById":["id"],"getDefaultUser":["fallback"],"readSettings":[],"removeCluster":["id"],"createCluster":["options"],"getUsers":[]}', 'onelauncher':'{"set_window_style":["decorations"],"return_error":[],"open_dev_tools":[]}', 'events':'{"ingress":["event"],"message":["event"],"process":["event"]}' }
export type Router = { 'events': { ingress: (event: IngressPayload) => Promise<void>,
message: (event: MessagePayload) => Promise<void>,
process: (event: ProcessPayload) => Promise<void> },
'onelauncher': { return_error: () => Promise<null>,
open_dev_tools: () => Promise<void>,
set_window_style: (decorations: boolean) => Promise<void> },
'core': { getClusters: () => Promise<ClusterModel[]>,
const ARGS_MAP = { 'events':'{"ingress":["event"],"message":["event"],"process":["event"]}', 'core':'{"removeUser":["uuid"],"writeSettings":["setting"],"updateClusterById":["id","request"],"getScreenshots":["id"],"getClusters":[],"getWorlds":["id"],"getGameVersions":[],"getPackage":["provider","slug"],"getLoadersForVersion":["mc_version"],"getMultiplePackages":["provider","slugs"],"getPackageUser":["provider","slug"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getUsersFromAuthor":["provider","author"],"searchPackages":["provider","query"],"getUser":["uuid"],"getProfileOrDefault":["name"],"updateClusterProfile":["name","profile"],"getPackageVersions":["provider","slug","mc_versions","loaders","offset","limit"],"launchCluster":["id","uuid"],"setDefaultUser":["uuid"],"openMsaLogin":[],"getGlobalProfile":[],"getClusterById":["id"],"getDefaultUser":["fallback"],"readSettings":[],"removeCluster":["id"],"createCluster":["options"],"getUsers":[]}', 'onelauncher':'{"set_window_style":["decorations"],"return_error":[],"open_dev_tools":[]}' }
export type Router = { 'core': { getClusters: () => Promise<ClusterModel[]>,
getClusterById: (id: bigint) => Promise<ClusterModel | null>,
removeCluster: (id: bigint) => Promise<null>,
createCluster: (options: CreateCluster) => Promise<ClusterModel>,
@ -246,7 +240,13 @@ getMultiplePackages: (provider: Provider, slugs: string[]) => Promise<ManagedPac
getPackageVersions: (provider: Provider, slug: string, mcVersions: string[] | null, loaders: GameLoader[] | null, offset: bigint, limit: bigint) => Promise<Paginated<ManagedVersion>>,
getPackageUser: (provider: Provider, slug: string) => Promise<ManagedUser>,
downloadPackage: (provider: Provider, packageId: string, versionId: string, clusterId: bigint, skipCompatibility: boolean | null) => Promise<PackageModel>,
getUsersFromAuthor: (provider: Provider, author: PackageAuthor) => Promise<ManagedUser[]> } };
getUsersFromAuthor: (provider: Provider, author: PackageAuthor) => Promise<ManagedUser[]> },
'events': { ingress: (event: IngressPayload) => Promise<void>,
message: (event: MessagePayload) => Promise<void>,
process: (event: ProcessPayload) => Promise<void> },
'onelauncher': { return_error: () => Promise<null>,
open_dev_tools: () => Promise<void>,
set_window_style: (decorations: boolean) => Promise<void> } };
export type { InferCommandOutput }

View file

@ -4,7 +4,7 @@ import type { UndefinedInitialDataOptions } from '@tanstack/react-query';
import type { Dispatch, SetStateAction } from 'react';
import { bindings } from '@/main';
import { PROVIDERS } from '@/utils';
import { useCommand } from '@onelauncher/common';
import { useCommand, useCommandMut } from '@onelauncher/common';
import { useNavigate } from '@tanstack/react-router';
import { createContext, useContext, useEffect, useMemo, useState } from 'react';
@ -79,3 +79,7 @@ export function usePackageData(provider: Provider, slug: string, options?: Omit<
export function usePackageVersions(provider: Provider, slug: string, { mc_versions, loaders, offset, limit, ...options }: { mc_versions?: Array<string> | null; loaders?: Array<GameLoader> | null; offset?: number; limit: number } & Omit<UndefinedInitialDataOptions<Paginated<ManagedVersion>>, 'queryKey' | 'queryFn'>, key: false | BindingCommands | (string & {}) = `getPackageVersions.${provider}.${slug}.${mc_versions?.join('')}.${loaders?.join('')}`) {
return useCommand(key, () => bindings.core.getPackageVersions(provider, slug, mc_versions ?? null, loaders ?? null, (offset ?? 0) as unknown as bigint, limit as unknown as bigint), options);
}
export function useDownloadPackage(cluster: ClusterModel, provider: Provider, version: ManagedVersion, skipCompatibility = false) {
return useCommandMut(() => bindings.core.downloadPackage(provider, version.project_id, version.version_id, cluster.id, skipCompatibility));
}

View file

@ -1,7 +1,7 @@
import type { ClusterModel, ManagedPackage, ManagedUser, ManagedVersion, PackageDonationUrl, Provider } from '@/bindings.gen';
import type { HTMLProps } from 'react';
import Modal from '@/components/overlay/Modal';
import { useBrowserContext, usePackageData, usePackageVersions } from '@/hooks/useBrowser';
import { useBrowserContext, useDownloadPackage, usePackageData, usePackageVersions } from '@/hooks/useBrowser';
import { ChooseClusterModal, useClusters } from '@/hooks/useCluster';
import usePagination from '@/hooks/usePagination';
import { bindings } from '@/main';
@ -253,7 +253,7 @@ function InstallButton() {
const [open, setOpen] = useState(false);
const clusters = useClusters();
const browserContext = useBrowserContext();
const { data: versions } = usePackageVersions(provider, slug, {
const { data: versions, isLoading: versionsLoading } = usePackageVersions(provider, slug, {
mc_versions: browserContext.cluster ? [browserContext.cluster.mc_version] : [],
loaders: browserContext.cluster ? [browserContext.cluster.mc_loader] : [],
limit: 1,
@ -264,11 +264,17 @@ function InstallButton() {
return versions.items[0];
}, [browserContext.cluster, versions]);
function download() {
if (!version || !browserContext.cluster || !includes(PROVIDERS, provider))
return false;
downloadPackage(browserContext.cluster, provider, version);
}
const download = useDownloadPackage(browserContext.cluster!, provider, version!, true);
const downloadRef = useRef(download);
useEffect(() => {
downloadRef.current.reset();
}, [browserContext.cluster]);
// function download() {
// if (!version || !browserContext.cluster || !includes(PROVIDERS, provider))
// return false;
// downloadPackage(browserContext.cluster, provider, version);
// }
return (
@ -276,13 +282,13 @@ function InstallButton() {
<Button
className="max-w-full flex-1 rounded-r-none disabled:text-white/50 disabled:bg-blue-900"
color="primary"
isDisabled={!version}
onClick={download}
isDisabled={!version || download.isPending || download.isSuccess}
onClick={() => download.mutate()}
>
<Download01Icon />
<div className="w-full text-sm">
{
browserContext.cluster
<Show when={download.isIdle}>
{browserContext.cluster
? version
? (
<span>
@ -291,9 +297,24 @@ function InstallButton() {
<span className="text-md font-semibold">{browserContext.cluster.name}</span>
</span>
)
: `No matching version found`
: 'Select a Cluster'
}
: versionsLoading ? 'Looking for a version...' : 'No matching version found'
: 'Select a Cluster'}
</Show>
<Show when={download.isPending}>
<span>
Downloading latest to
<br />
<span className="text-md font-semibold">{browserContext.cluster?.name ?? 'Unknown'}</span>
</span>
</Show>
<Show when={download.isSuccess}>
<span>
Installed latest into
<br />
<span className="text-md font-semibold">{browserContext.cluster?.name ?? 'Unknown'}</span>
</span>
</Show>
</div>
</Button>
@ -390,18 +411,19 @@ function Versions() {
itemsCount: versions?.total as unknown as number,
itemsPerPage: versions?.limit as unknown as number,
});
const paginationRef = useRef(pagination);
useEffect(() => {
setOffset(pagination.offset);
}, [pagination.offset]);
useEffect(() => {
pagination.reset();
paginationRef.current.reset();
}, [versions?.total]);
return (
<div className="flex flex-col">
<div className="flex flex-col w-full">
<div className="flex justify-between">
<pagination.Navigation />
</div>
<Table className="border-separate border-spacing-x-none border-spacing-y-1">
<Table className="border-separate border-spacing-x-none border-spacing-y-1 w-full">
<TableHeader className="text-left">
<Column className="pr-2" />
<Column className="pr-4" isRowHeader>Name</Column>
@ -425,7 +447,7 @@ function VersionRow({ version }: { version: ManagedVersion }) {
if (!includes(PROVIDERS, provider))
throw new Error('invalid provider');
return (
<Row className="my-2 bg-page-elevated px-4 [&>td]:py-4">
<Row className="my-2 bg-page-elevated px-4 [&>td]:py-4 w-full">
<Cell className="p-4 my-2 bg-component-bg rounded-l-xl">
<Tooltip text={upperFirst(version.release_type)}>
<div className={`${colorForType(version.release_type)} h-8 w-8 flex items-center justify-center rounded-md`}>