added logic and some translate

This commit is contained in:
Kelvin 2025-01-13 01:38:29 -03:00
parent d4be5b8c66
commit 6a429f9f39
6 changed files with 84 additions and 7 deletions

View file

@ -258,6 +258,7 @@
"download_source_errored": "Errored",
"sync_download_sources": "Sync sources",
"removed_download_source": "Download source removed",
"removed_download_sources": "Download sources removed",
"added_download_source": "Added download source",
"download_sources_synced": "All download sources are synced",
"insert_valid_json_url": "Insert a valid JSON url",

View file

@ -246,6 +246,7 @@
"download_source_errored": "Falhou",
"sync_download_sources": "Sincronizar",
"removed_download_source": "Fonte removida",
"removed_download_sources": "Fontes removidas",
"added_download_source": "Fonte adicionada",
"download_sources_synced": "As fontes foram sincronizadas",
"insert_valid_json_url": "Insira a url de um JSON válido",

View file

@ -10,6 +10,8 @@ export interface ConfirmationModalProps extends Omit<ModalProps, "children"> {
onConfirm: () => void;
onCancel?: () => void;
buttonsIsDisabled?: boolean
}
export function ConfirmationModal({
@ -18,6 +20,7 @@ export function ConfirmationModal({
descriptionText,
onConfirm,
onCancel,
buttonsIsDisabled = false,
...props
}: ConfirmationModalProps) {
const handleCancelClick = () => {
@ -35,10 +38,10 @@ export function ConfirmationModal({
<p className={styles.descriptionText}>{descriptionText}</p>
<div className={styles.actions}>
<Button theme="outline" onClick={handleCancelClick}>
<Button theme="outline" disabled={buttonsIsDisabled} onClick={handleCancelClick}>
{cancelButtonLabel}
</Button>
<Button theme="danger" onClick={onConfirm}>
<Button theme="danger" disabled={buttonsIsDisabled} onClick={onConfirm}>
{confirmButtonLabel}
</Button>
</div>

View file

@ -56,3 +56,8 @@ export const navigateToCatalogueButton = style({
textDecoration: "none",
},
});
export const removeAllSourcesButton = style({
display: 'flex',
justifyContent: 'flex-end'
})

View file

@ -1,11 +1,11 @@
import { useContext, useEffect, useState } from "react";
import { TextField, Button, Badge } from "@renderer/components";
import { TextField, Button, Badge, ConfirmationModal } from "@renderer/components";
import { useTranslation } from "react-i18next";
import * as styles from "./settings-download-sources.css";
import type { DownloadSource } from "@types";
import { NoEntryIcon, PlusCircleIcon, SyncIcon } from "@primer/octicons-react";
import { NoEntryIcon, PlusCircleIcon, SyncIcon, XIcon } from "@primer/octicons-react";
import { AddDownloadSourceModal } from "./add-download-source-modal";
import { useAppDispatch, useRepacks, useToast } from "@renderer/hooks";
import { DownloadSourceStatus } from "@shared";
@ -16,6 +16,8 @@ import { useNavigate } from "react-router-dom";
import { setFilters, clearFilters } from "@renderer/features";
export function SettingsDownloadSources() {
const [showConfirmationDeleteAllSourcesModal, setShowConfirmationDeleteAllSourcesModal] =
useState(false);
const [showAddDownloadSourceModal, setShowAddDownloadSourceModal] =
useState(false);
const [downloadSources, setDownloadSources] = useState<DownloadSource[]>([]);
@ -23,6 +25,8 @@ export function SettingsDownloadSources() {
useState(false);
const [isRemovingDownloadSource, setIsRemovingDownloadSource] =
useState(false);
const [isFetchingSources, setIsFetchingSources] =
useState(true);
const { sourceUrl, clearSourceUrl } = useContext(settingsContext);
@ -41,7 +45,9 @@ export function SettingsDownloadSources() {
.sortBy("createdAt")
.then((sources) => {
setDownloadSources(sources.reverse());
});
}).finally(() => {
setIsFetchingSources(false)
})
};
useEffect(() => {
@ -68,6 +74,24 @@ export function SettingsDownloadSources() {
};
};
const handleRemoveAllDowloadSources = () => {
setIsRemovingDownloadSource(true);
const id = crypto.randomUUID();
const channel = new BroadcastChannel(`download_sources:delete_all:${id}`);
downloadSourcesWorker.postMessage(["DELETE_ALL_DOWNLOAD_SOURCES", id]);
channel.onmessage = () => {
showSuccessToast(t("removed_download_sources"));
getDownloadSources();
setShowConfirmationDeleteAllSourcesModal(false)
channel.close();
updateRepacks();
}
}
const handleAddDownloadSource = async () => {
await getDownloadSources();
showSuccessToast(t("added_download_source"));
@ -116,6 +140,18 @@ export function SettingsDownloadSources() {
onAddDownloadSource={handleAddDownloadSource}
/>
<ConfirmationModal
cancelButtonLabel="Não"
confirmButtonLabel="Sim, excluir"
descriptionText="Você ira excluir todas as fontes de dowload"
clickOutsideToClose={false}
onConfirm={handleRemoveAllDowloadSources}
visible={showConfirmationDeleteAllSourcesModal}
title={"Excluir todas as fontes de dowload"}
onClose={() => setShowConfirmationDeleteAllSourcesModal(false)}
buttonsIsDisabled={isRemovingDownloadSource}
/>
<p>{t("download_sources_description")}</p>
<div className={styles.downloadSourcesHeader}>
@ -196,6 +232,21 @@ export function SettingsDownloadSources() {
</li>
))}
</ul>
{!isFetchingSources && downloadSources.length >= 2 && (
<div className={styles.removeAllSourcesButton}>
<Button
type="button"
theme="danger"
onClick={() => setShowConfirmationDeleteAllSourcesModal(true)}
disabled={isRemovingDownloadSource}
>
<XIcon />
Remover todas as fontes de dowload
</Button>
</div>
)}
</>
);
}

View file

@ -21,9 +21,10 @@ export const downloadSourceSchema = z.object({
type Payload =
| ["IMPORT_DOWNLOAD_SOURCE", string]
| ["DELETE_DOWNLOAD_SOURCE", number]
| ["DELETE_DOWNLOAD_SOURCE", number]
| ["VALIDATE_DOWNLOAD_SOURCE", string]
| ["SYNC_DOWNLOAD_SOURCES", string];
| ["SYNC_DOWNLOAD_SOURCES", string]
| ["DELETE_ALL_DOWNLOAD_SOURCES", string];
export type SteamGamesByLetter = Record<string, { id: string; name: string }[]>;
@ -114,6 +115,13 @@ const deleteDownloadSource = async (id: number) => {
});
};
const deleteAllDowloadsSources = async () => {
await db.transaction("rw", repacksTable, downloadSourcesTable, async () => {
await repacksTable.clear()
await downloadSourcesTable.clear();
});
};
self.onmessage = async (event: MessageEvent<Payload>) => {
const [type, data] = event.data;
@ -132,6 +140,14 @@ self.onmessage = async (event: MessageEvent<Payload>) => {
});
}
if (type === 'DELETE_ALL_DOWNLOAD_SOURCES') {
await deleteAllDowloadsSources()
const channel = new BroadcastChannel(`download_sources:delete_all:${data}`);
channel.postMessage(true)
}
if (type === "DELETE_DOWNLOAD_SOURCE") {
await deleteDownloadSource(data);