feat: adding i18n for cloud sync

This commit is contained in:
Chubby Granny Chaser 2024-09-25 22:22:26 +01:00
parent 32fa69627c
commit 9b5e13ad35
No known key found for this signature in database
13 changed files with 59 additions and 27 deletions

View file

@ -130,7 +130,20 @@
"download": "Download", "download": "Download",
"executable_path_in_use": "Executable already in use by \"{{game}}\"", "executable_path_in_use": "Executable already in use by \"{{game}}\"",
"warning": "Warning:", "warning": "Warning:",
"hydra_needs_to_remain_open": "for this download, Hydra needs to remain open util its conclusion. In case Hydra closes before the conclusion, you will lose your progress." "hydra_needs_to_remain_open": "for this download, Hydra needs to remain open util its conclusion. In case Hydra closes before the conclusion, you will lose your progress.",
"cloud_save": "Cloud save",
"cloud_save_description": "Save your progress in the cloud and continue playing on any device",
"backups": "Backups",
"install_backup": "Install",
"delete_backup": "Delete",
"create_backup": "Create backup",
"last_backup_date": "Last backup on {{date}}",
"no_backup_preview": "Hydra could not locate any save games for this game",
"restoring_backup": "Restoring backup…",
"uploading_backup": "Uploading backup…",
"no_backups": "You haven't created any backups for this game yet",
"backup_uploaded": "Backup uploaded",
"backup_deleted": "Backup deleted"
}, },
"activation": { "activation": {
"title": "Activate Hydra", "title": "Activate Hydra",

View file

@ -126,7 +126,21 @@
"download": "Baixar", "download": "Baixar",
"executable_path_in_use": "Executável em uso por \"{{game}}\"", "executable_path_in_use": "Executável em uso por \"{{game}}\"",
"warning": "Aviso:", "warning": "Aviso:",
"hydra_needs_to_remain_open": "para este download, o Hydra precisa ficar aberto até a conclusão. Caso o Hydra encerre antes da conclusão, perderá seu progresso." "hydra_needs_to_remain_open": "para este download, o Hydra precisa ficar aberto até a conclusão. Caso o Hydra encerre antes da conclusão, perderá seu progresso.",
"cloud_save": "Salvamento em nuvem",
"cloud_save_description": "Matenha seu progresso na nuvem e continue de onde parou em qualquer dispositivo",
"backups": "Backups",
"install_backup": "Restaurar",
"delete_backup": "Apagar",
"create_backup": "Criar backup",
"last_backup_date": "Último backup em {{date}}",
"no_backup_preview": "Hydra não encontrou nenhum save para este jogo",
"restoring_backup": "Restaurando backup…",
"uploading_backup": "Criando backup…",
"no_backups": "Você ainda não fez nenhum backup deste jogo",
"backup_uploaded": "Backup criado",
"backup_deleted": "Backup apagado"
}, },
"activation": { "activation": {
"title": "Ativação", "title": "Ativação",

View file

@ -58,12 +58,12 @@ import "./profile/update-profile";
import "./profile/process-profile-image"; import "./profile/process-profile-image";
import "./profile/send-friend-request"; import "./profile/send-friend-request";
import "./profile/sync-friend-requests"; import "./profile/sync-friend-requests";
import "./cloud-sync/download-game-artifact"; import "./cloud-save/download-game-artifact";
import "./cloud-sync//get-game-artifacts"; import "./cloud-save/get-game-artifacts";
import "./cloud-sync/get-game-backup-preview"; import "./cloud-save/get-game-backup-preview";
import "./cloud-sync/upload-save-game"; import "./cloud-save/upload-save-game";
import "./cloud-sync/check-game-cloud-sync-support"; import "./cloud-save/check-game-cloud-sync-support";
import "./cloud-sync/delete-game-artifact"; import "./cloud-save/delete-game-artifact";
import { isPortableVersion } from "@main/helpers"; import { isPortableVersion } from "@main/helpers";
ipcMain.handle("ping", () => "pong"); ipcMain.handle("ping", () => "pong");

View file

@ -115,7 +115,7 @@ contextBridge.exposeInMainWorld("electron", {
getDiskFreeSpace: (path: string) => getDiskFreeSpace: (path: string) =>
ipcRenderer.invoke("getDiskFreeSpace", path), ipcRenderer.invoke("getDiskFreeSpace", path),
/* Cloud sync */ /* Cloud save */
uploadSaveGame: (objectId: string, shop: GameShop) => uploadSaveGame: (objectId: string, shop: GameShop) =>
ipcRenderer.invoke("uploadSaveGame", objectId, shop), ipcRenderer.invoke("uploadSaveGame", objectId, shop),
downloadGameArtifact: ( downloadGameArtifact: (

View file

@ -115,7 +115,7 @@ declare global {
/* Hardware */ /* Hardware */
getDiskFreeSpace: (path: string) => Promise<DiskSpace>; getDiskFreeSpace: (path: string) => Promise<DiskSpace>;
/* Cloud sync */ /* Cloud save */
uploadSaveGame: (objectId: string, shop: GameShop) => Promise<void>; uploadSaveGame: (objectId: string, shop: GameShop) => Promise<void>;
downloadGameArtifact: ( downloadGameArtifact: (
objectId: string, objectId: string,

View file

@ -16,6 +16,7 @@ import {
} from "@primer/octicons-react"; } from "@primer/octicons-react";
import { useToast } from "@renderer/hooks"; import { useToast } from "@renderer/hooks";
import { GameBackup, gameBackupsTable } from "@renderer/dexie"; import { GameBackup, gameBackupsTable } from "@renderer/dexie";
import { useTranslation } from "react-i18next";
export interface CloudSyncModalProps export interface CloudSyncModalProps
extends Omit<ModalProps, "children" | "title"> {} extends Omit<ModalProps, "children" | "title"> {}
@ -24,6 +25,8 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
const [deletingArtifact, setDeletingArtifact] = useState(false); const [deletingArtifact, setDeletingArtifact] = useState(false);
const [lastBackup, setLastBackup] = useState<GameBackup | null>(null); const [lastBackup, setLastBackup] = useState<GameBackup | null>(null);
const { t } = useTranslation("game_details");
const { const {
artifacts, artifacts,
backupPreview, backupPreview,
@ -44,7 +47,7 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
try { try {
await deleteGameArtifact(gameArtifactId); await deleteGameArtifact(gameArtifactId);
showSuccessToast("backup_successfully_deleted"); showSuccessToast(t("backup_deleted"));
} catch (err) { } catch (err) {
showErrorToast("backup_deletion_failed"); showErrorToast("backup_deletion_failed");
} finally { } finally {
@ -64,7 +67,7 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
return ( return (
<span style={{ display: "flex", alignItems: "center", gap: 8 }}> <span style={{ display: "flex", alignItems: "center", gap: 8 }}>
<SyncIcon /> <SyncIcon />
creating_backup {t("uploading_backup")}
</span> </span>
); );
} }
@ -73,34 +76,36 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
return ( return (
<span style={{ display: "flex", alignItems: "center", gap: 8 }}> <span style={{ display: "flex", alignItems: "center", gap: 8 }}>
<SyncIcon /> <SyncIcon />
restoring_backup {t("restoring_backup")}
</span> </span>
); );
} }
if (lastBackup) { if (lastBackup) {
return ( return (
<p style={{ display: "flex", alignItems: "center", gap: 8 }}> <span style={{ display: "flex", alignItems: "center", gap: 8 }}>
<CheckCircleFillIcon /> <CheckCircleFillIcon />
Último backup em {format(lastBackup.createdAt, "dd/MM/yyyy HH:mm")} {t("last_backup_date", {
</p> date: format(lastBackup.createdAt, "dd/MM/yyyy HH:mm"),
})}
</span>
); );
} }
if (!backupPreview) { if (!backupPreview) {
return "no_backup_preview"; return t("no_backup_preview");
} }
return "no_artifacts"; return t("no_backups");
}, [uploadingBackup, lastBackup, backupPreview, restoringBackup]); }, [uploadingBackup, lastBackup, backupPreview, restoringBackup, t]);
const disableActions = uploadingBackup || restoringBackup || deletingArtifact; const disableActions = uploadingBackup || restoringBackup || deletingArtifact;
return ( return (
<Modal <Modal
visible={visible} visible={visible}
title="cloud_sync" title={t("cloud_save")}
description="cloud_sync_description" description={t("cloud_save_description")}
onClose={onClose} onClose={onClose}
large large
> >
@ -114,7 +119,7 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
> >
<div style={{ display: "flex", gap: 4, flexDirection: "column" }}> <div style={{ display: "flex", gap: 4, flexDirection: "column" }}>
<h2>{gameTitle}</h2> <h2>{gameTitle}</h2>
{backupStateLabel} <p>{backupStateLabel}</p>
</div> </div>
<Button <Button
@ -123,11 +128,11 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
disabled={disableActions || !backupPreview} disabled={disableActions || !backupPreview}
> >
<UploadIcon /> <UploadIcon />
create_backup {t("create_backup")}
</Button> </Button>
</div> </div>
<h2 style={{ marginBottom: 16 }}>backups</h2> <h2 style={{ marginBottom: 16 }}>{t("backups")}</h2>
<ul className={styles.artifacts}> <ul className={styles.artifacts}>
{artifacts.map((artifact) => ( {artifacts.map((artifact) => (
@ -162,7 +167,7 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
disabled={disableActions} disabled={disableActions}
> >
<DownloadIcon /> <DownloadIcon />
install_artifact {t("install_backup")}
</Button> </Button>
<Button <Button
type="button" type="button"
@ -171,7 +176,7 @@ export function CloudSyncModal({ visible, onClose }: CloudSyncModalProps) {
disabled={disableActions} disabled={disableActions}
> >
<TrashIcon /> <TrashIcon />
delete_artifact {t("delete_backup")}
</Button> </Button>
</div> </div>
</li> </li>

View file

@ -132,7 +132,7 @@ export function GameDetailsContent() {
style={{ width: 26, position: "absolute", top: -3 }} style={{ width: 26, position: "absolute", top: -3 }}
/> />
</div> </div>
cloud_sync {t("cloud_save")}
</button> </button>
)} )}
</div> </div>