feat: adding automatic cloud sync

This commit is contained in:
Chubby Granny Chaser
2025-03-09 19:14:24 +00:00
parent 886e176b08
commit ed699a8dee
19 changed files with 275 additions and 96 deletions

View File

@@ -7,7 +7,7 @@ export interface CheckboxFieldProps
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
> {
label: string;
label: string | React.ReactNode;
}
export function CheckboxField({ label, ...props }: CheckboxFieldProps) {

View File

@@ -31,6 +31,7 @@ import type {
TorBoxUser,
Theme,
Badge,
Auth,
} from "@types";
import type { AxiosProgressEvent } from "axios";
import type disk from "diskusage";
@@ -87,6 +88,11 @@ declare global {
getDevelopers: () => Promise<string[]>;
/* Library */
toggleAutomaticCloudSync: (
shop: GameShop,
objectId: string,
automaticCloudSync: boolean
) => Promise<void>;
addGameToLibrary: (
shop: GameShop,
objectId: string,
@@ -237,6 +243,7 @@ declare global {
onSignOut: (cb: () => void) => () => Electron.IpcRenderer;
/* User */
getAuth: () => Promise<Auth | null>;
getUser: (userId: string) => Promise<UserProfile | null>;
blockUser: (userId: string) => Promise<void>;
unblockUser: (userId: string) => Promise<void>;

View File

@@ -23,6 +23,20 @@
}
}
&__cloud-sync-label {
display: flex;
gap: globals.$spacing-unit;
align-items: center;
}
&__cloud-sync-hydra-cloud {
background: linear-gradient(270deg, #16b195 50%, #3e62c0 100%);
color: #fff;
padding: 0 globals.$spacing-unit;
border-radius: 4px;
font-size: 12px;
}
&__row {
display: flex;
gap: globals.$spacing-unit;

View File

@@ -1,6 +1,6 @@
import { useContext, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Button, Modal, TextField } from "@renderer/components";
import { Button, CheckboxField, Modal, TextField } from "@renderer/components";
import type { LibraryGame } from "@types";
import { gameDetailsContext } from "@renderer/context";
import { DeleteGameModal } from "@renderer/pages/downloads/delete-game-modal";
@@ -34,12 +34,17 @@ export function GameOptionsModal({
achievements,
} = useContext(gameDetailsContext);
const { hasActiveSubscription } = useUserDetails();
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [showRemoveGameModal, setShowRemoveGameModal] = useState(false);
const [launchOptions, setLaunchOptions] = useState(game.launchOptions ?? "");
const [showResetAchievementsModal, setShowResetAchievementsModal] =
useState(false);
const [isDeletingAchievements, setIsDeletingAchievements] = useState(false);
const [automaticCloudSync, setAutomaticCloudSync] = useState(
game.automaticCloudSync ?? false
);
const {
removeGameInstaller,
@@ -183,6 +188,20 @@ export function GameOptionsModal({
}
};
const handleToggleAutomaticCloudSync = async (
event: React.ChangeEvent<HTMLInputElement>
) => {
setAutomaticCloudSync(event.target.checked);
await window.electron.toggleAutomaticCloudSync(
game.shop,
game.objectId,
event.target.checked
);
updateGame();
};
return (
<>
<DeleteGameModal
@@ -266,6 +285,20 @@ export function GameOptionsModal({
</div>
</div>
<CheckboxField
label={
<div className="game-options-modal__cloud-sync-label">
{t("enable_automatic_cloud_sync")}
<span className="game-options-modal__cloud-sync-hydra-cloud">
Hydra Cloud
</span>
</div>
}
checked={automaticCloudSync}
disabled={!hasActiveSubscription || !game.executablePath}
onChange={handleToggleAutomaticCloudSync}
/>
{shouldShowWinePrefixConfiguration && (
<div className="game-options-modal__wine-prefix">
<div className="game-options-modal__header">