Skip to content

Commit

Permalink
Update profile downloadHub (#47)
Browse files Browse the repository at this point in the history
* Update profile downloadHub (#45)

* GL-62 (#40)

* GL-65 (#43)

* Adding jvm args for WebClient

* Fix to camelCase

* Adding custom auth

* GL-41 Background image

* Styling

* GL-65

* Update profile downloadHub

* Updating the development branch (#46)

* GL-62 (#40)

* GL-65 (#43)

* Adding jvm args for WebClient

* Fix to camelCase

* Adding custom auth

* GL-41 Background image

* Styling

* GL-65

---------

Co-authored-by: Akemiko <[email protected]>

* GL-00: Рефакторинг

---------

Co-authored-by: Akemiko <[email protected]>
Co-authored-by: GamerVII-NET <[email protected]>
Co-authored-by: Терентьев Вадим Алексеевич <[email protected]>
  • Loading branch information
4 people authored Jun 19, 2024
1 parent a7b3fc2 commit 8566ced
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 34 deletions.
1 change: 1 addition & 0 deletions src/shared/api/contracts/profiles/ProfileBaseEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type ProfileBaseEntity = {
launchVersion: string;
jvmArguments: string;
iconBase64: string;
state: string;
};

export type ProfileExtendedBaseEntity = {
Expand Down
1 change: 1 addition & 0 deletions src/shared/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from "./integration";
export * from "./storages";
export * from "./systems";
export * from "./textures";
export * from "./profileState";
11 changes: 11 additions & 0 deletions src/shared/enums/profileState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export enum ProfileState {
PROFILE_STATE_CREATED = 0, // Профиль создан
PROFILE_STATE_LOADING = 1, // Профиль загружается
PROFILE_STATE_ACTIVE = 2, // Профиль активен
}

export enum ProfileStateOption {
"OPTION_0" = "Создан", // Профиль создан
"OPTION_1" = "Загружается Engine", // Профиль загружается
"OPTION_2" = "Активен", // Профиль активен
}
75 changes: 57 additions & 18 deletions src/widgets/client-hub/lib/useConnectionHub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,16 @@ export const useConnectionHub = (props: ConnectionHubProps) => {
const accessToken = getStorageAccessToken();

const [connectionHub, setConnectionHub] = useState<HubConnection | null>(null);
const [progressPercent, setProgressPercent] = useState(0);

const [percentStage, setPercentStage] = useState(0);
const [percentAllStages, setPercentAllStages] = useState(0);

const [isRestoring, setIsRestoring] = useState(false);

const [logs, setLogs] = useState<string[] | null>(null);

const [isPacked, setIsPacked] = useState(false);

useEffect(() => {
if (isLoading || !accessToken) return;

Expand All @@ -38,13 +45,33 @@ export const useConnectionHub = (props: ConnectionHubProps) => {

await connection.start();

connection.on("BlockRestore", () => {
setIsRestoring(true);
if (profile?.hasUpdate == false) setIsRestoring(true);

connection.on("ChangeProgress", (profileName, percent) => {
if (profileName == profile?.profileName) {
setIsRestoring(true);
setPercentStage(percent);
}
});

connection.on("FullProgress", (profileName, percent) => {
if (profileName == profile?.profileName) {
setIsRestoring(true);
setIsPacked(true);
setPercentAllStages(percent);
}
});

connection.on("OnException", (profileName, exception: string) => {
if (profileName == profile?.profileName) {
setLogs((prev) => (prev ? [...prev, exception] : [exception]));
}
});

connection.on("ChangeProgress", (percent) => {
setIsRestoring(true);
setProgressPercent(percent);
connection.on("Log", (profileName, log: string) => {
if (profileName == profile?.profileName) {
setLogs((prev) => (prev ? [...prev, log] : [log]));
}
});

connection.on("Message", (msg) => {
Expand All @@ -54,21 +81,28 @@ export const useConnectionHub = (props: ConnectionHubProps) => {
});
});

connection.on("SuccessInstalled", () => {
setIsRestoring(false);
setProgressPercent(0);
toast({
title: "Успешно",
description: "Клиент успешно загружен",
});
connection.on("SuccessInstalled", (profileName) => {
if (profileName == profile?.profileName) {
setIsPacked(false);
setIsRestoring(false);
setPercentStage(0);
setPercentAllStages(0);
setLogs(null);
toast({
title: "Успешно",
description: `Профиль ${profileName} успешно загружен`,
});
}
});

connection.on("SuccessPacked", () => {
setIsRestoring(false);
setProgressPercent(0);
connection.on("SuccessPacked", (profileName) => {
if (profileName == profile?.profileName) {
setIsRestoring(false);
setPercentStage(0);
}
toast({
title: "Успешно",
description: "Клиент успешно собран",
description: `Профиль ${profileName} успешно собран`,
});
});
} catch (error) {
Expand All @@ -84,6 +118,7 @@ export const useConnectionHub = (props: ConnectionHubProps) => {
}, []);

const onDownloadDistributive = () => {
setIsPacked(true);
setIsRestoring(true);
connectionHub
?.invoke("Restore", profile?.profileName)
Expand All @@ -100,6 +135,7 @@ export const useConnectionHub = (props: ConnectionHubProps) => {
};

const onBuildDistributive = () => {
setIsPacked(false);
setIsRestoring(true);
connectionHub
?.invoke("Build", profile?.profileName)
Expand All @@ -119,6 +155,9 @@ export const useConnectionHub = (props: ConnectionHubProps) => {
onDownloadDistributive,
onBuildDistributive,
isDisable: isRestoring,
progress: progressPercent,
isPacked,
percentStage,
percentAllStages,
logs,
};
};
70 changes: 58 additions & 12 deletions src/widgets/client-hub/ui/DownloadClientHub.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
"use client";

import React from "react";
import React, { useEffect, useRef } from "react";

import { ProfileExtendedBaseEntity } from "@/shared/api/contracts";
import { Button } from "@/shared/ui/button";
import { Progress } from "@/shared/ui/progress";
import { Textarea } from "@/shared/ui/textarea";
import { Icons } from "@/shared/ui/icons";

import { useConnectionHub } from "../lib/useConnectionHub";
import { ProfileExtendedBaseEntity } from "@/shared/api/contracts";

interface DownloadClientHubProps {
profile?: ProfileExtendedBaseEntity;
isLoading?: boolean;
}

export function DownloadClientHub(props: DownloadClientHubProps) {
const { onDownloadDistributive, onBuildDistributive, isDisable, progress } =
useConnectionHub(props);
const {
onDownloadDistributive,
onBuildDistributive,
isDisable,
isPacked,
percentStage,
percentAllStages,
logs,
} = useConnectionHub(props);

const textareaRef = useRef<HTMLTextAreaElement>(null);
useEffect(() => {
if (textareaRef.current) {
textareaRef.current.scrollTop = textareaRef.current.scrollHeight;
}
}, [logs]);

return (
<>
Expand All @@ -29,6 +46,7 @@ export function DownloadClientHub(props: DownloadClientHubProps) {
onClick={onDownloadDistributive}
disabled={isDisable || !props.profile || !props.profile.hasUpdate}
>
{isDisable && <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />}
Загрузить
</Button>
</div>
Expand All @@ -44,19 +62,47 @@ export function DownloadClientHub(props: DownloadClientHubProps) {
onClick={onBuildDistributive}
disabled={isDisable || !props.profile || !props.profile.hasUpdate}
>
{isDisable && <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />}
Собрать
</Button>
</div>
</div>
{Boolean(progress) && (
<div className="flex gap-x-8">
<div className="flex flex-col gap-y-1 w-96">
<h6 className="text-sm font-bold">Прогресс</h6>
<p className="text-sm text-gray-700 dark:text-gray-300">Выполнено на {progress}% из 100%</p>
</div>
<div className="flex flex-col gap-y-1 w-[32rem]">
<Progress className="h-2" value={progress} />
{Boolean(isDisable) && (
<div className="grid gap-y-4">
<div className="flex gap-x-8">
<div className="flex flex-col gap-y-1 w-96">
<h6 className="text-sm font-bold">Прогресс</h6>
<p className="text-sm text-gray-700 dark:text-gray-300">
Выполнено на {percentStage}% из 100%
</p>
</div>
<div className="flex flex-col gap-y-1 w-[32rem]">
<Progress className="h-2" value={percentStage} />
</div>
</div>
{Boolean(isPacked) && logs && (
<div>
<div className="flex gap-x-8">
<div className="flex flex-col gap-y-1 w-96">
<h6 className="text-sm font-bold">Полный прогресс</h6>
<p className="text-sm text-gray-700 dark:text-gray-300">
Выполнено на {percentAllStages}% из 100%
</p>
</div>
<div className="flex flex-col gap-y-1 w-[32rem]">
<Progress className="h-2" value={percentAllStages} />
</div>
</div>
<div className="my-4">
<Textarea
ref={textareaRef}
value={logs.join("\n")}
className="h-64 max-h-64"
readOnly
/>
</div>
</div>
)}
</div>
)}
</>
Expand Down
27 changes: 23 additions & 4 deletions src/widgets/profiles-table/lib/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,22 @@ import { createColumnHelper } from "@tanstack/table-core";
import { Edit2Icon, Trash2Icon } from "lucide-react";

import { DataTableColumnHeader } from "@/entities/Table";
import { ProfileBaseEntity } from "@/shared/api/contracts";
import { DASHBOARD_PAGES } from "@/shared/routes";

import { Button } from "@/shared/ui/button";
import { Checkbox } from "@/shared/ui/checkbox";
import { ProfileBaseEntity } from "@/shared/api/contracts";
import { DASHBOARD_PAGES } from "@/shared/routes";
import { Icons } from "@/shared/ui/icons";
import { getFormatDate } from "@/shared/lib/getFormatDate/getFormatDate";
import { getFormatDate } from "@/shared/lib/utils";
import { ProfileStateOption } from "@/shared/enums";

enum ColumnHeader {
ICON = "",
NAME = "Название",
CREATED_AT = "Дата создания",
VERSION_LAUNCHER = "Версия",
VERSION_LAUNCHER = "Запускаемая версия",
GAME_VERSION = "Версия",
PROFILE_STATE = "Статус",
}

interface UseColumnsProps {
Expand Down Expand Up @@ -90,13 +94,28 @@ export const useColumns = (props: UseColumnsProps) => {
),
cell: ({ getValue }) => getValue(),
}),
columnsHelper.accessor("gameVersion", {
size: 100,
header: ({ column }) => (
<DataTableColumnHeader column={column} title={ColumnHeader.GAME_VERSION} />
),
cell: ({ getValue }) => getValue(),
}),
columnsHelper.accessor("createDate", {
size: 500,
header: ({ column }) => (
<DataTableColumnHeader column={column} title={ColumnHeader.CREATED_AT} />
),
cell: ({ getValue }) => getFormatDate(getValue()),
}),
columnsHelper.accessor("state", {
size: 50,
header: ({ column }) => (
<DataTableColumnHeader column={column} title={ColumnHeader.PROFILE_STATE} />
),
cell: ({ getValue }) =>
`${ProfileStateOption[`OPTION_${getValue()}` as keyof typeof ProfileStateOption]}`,
}),
columnsHelper.display({
size: 48,
id: "edit",
Expand Down

0 comments on commit 8566ced

Please sign in to comment.