feat: improving caching

This commit is contained in:
Chubby Granny Chaser
2025-10-15 13:58:40 +01:00
parent 136a44473f
commit 24106eaeab
35 changed files with 246 additions and 1061 deletions

View File

@@ -11,7 +11,6 @@ export const DOWNLOADER_NAME = {
[Downloader.Datanodes]: "Datanodes",
[Downloader.Mediafire]: "Mediafire",
[Downloader.TorBox]: "TorBox",
[Downloader.AllDebrid]: "All-Debrid",
[Downloader.Hydra]: "Nimbus",
};

View File

@@ -8,7 +8,6 @@ import type {
UserPreferences,
StartGameDownloadPayload,
RealDebridUser,
AllDebridUser,
UserProfile,
FriendRequestAction,
UpdateProfileRequest,
@@ -193,9 +192,6 @@ declare global {
) => Promise<void>;
/* User preferences */
authenticateRealDebrid: (apiToken: string) => Promise<RealDebridUser>;
authenticateAllDebrid: (
apiKey: string
) => Promise<AllDebridUser | { error_code: string }>;
authenticateTorBox: (apiToken: string) => Promise<TorBoxUser>;
getUserPreferences: () => Promise<UserPreferences | null>;
updateUserPreferences: (

View File

@@ -114,15 +114,6 @@ export function DownloadGroup({
return <p>{t("deleting")}</p>;
}
if (download.downloader === Downloader.AllDebrid) {
return (
<>
<p>{progress}</p>
<p>{t("alldebrid_size_not_supported")}</p>
</>
);
}
if (isGameDownloading) {
if (lastPacket?.isDownloadingMetadata) {
return <p>{t("downloading_metadata")}</p>;
@@ -190,15 +181,6 @@ export function DownloadGroup({
}
if (download.status === "active") {
if ((download.downloader as unknown as string) === "alldebrid") {
return (
<>
<p>{formatDownloadProgress(download.progress)}</p>
<p>{t("alldebrid_size_not_supported")}</p>
</>
);
}
return (
<>
<p>{formatDownloadProgress(download.progress)}</p>
@@ -293,9 +275,7 @@ export function DownloadGroup({
(download?.downloader === Downloader.RealDebrid &&
!userPreferences?.realDebridApiToken) ||
(download?.downloader === Downloader.TorBox &&
!userPreferences?.torBoxApiToken) ||
(download?.downloader === Downloader.AllDebrid &&
!userPreferences?.allDebridApiKey);
!userPreferences?.torBoxApiToken);
return [
{

View File

@@ -224,6 +224,12 @@ $hero-height: 300px;
margin-top: calc(globals.$spacing-unit * 3);
}
&__reviews-container {
display: flex;
flex-direction: column;
gap: calc(globals.$spacing-unit * 4);
}
&__reviews-separator {
height: 1px;
background: rgba(255, 255, 255, 0.1);
@@ -264,16 +270,6 @@ $hero-height: 300px;
}
&__review-item {
background: linear-gradient(
to right,
globals.$dark-background-color 0%,
globals.$dark-background-color 30%,
globals.$background-color 100%
);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 6px;
padding: calc(globals.$spacing-unit * 2);
margin-bottom: calc(globals.$spacing-unit * 2);
overflow: hidden;
word-wrap: break-word;
}

View File

@@ -501,6 +501,7 @@ export function GameReviews({
)}
<div
className="game-details__reviews-container"
style={{
opacity: reviewsLoading && reviews.length > 0 ? 0.5 : 1,
transition: "opacity 0.2s ease",

View File

@@ -117,8 +117,6 @@ export function DownloadSettingsModal({
return userPreferences?.realDebridApiToken;
if (downloader === Downloader.TorBox)
return userPreferences?.torBoxApiToken;
if (downloader === Downloader.AllDebrid)
return userPreferences?.allDebridApiKey;
if (downloader === Downloader.Hydra)
return isFeatureEnabled(Feature.Nimbus);
return true;
@@ -133,7 +131,6 @@ export function DownloadSettingsModal({
downloaders,
userPreferences?.realDebridApiToken,
userPreferences?.torBoxApiToken,
userPreferences?.allDebridApiKey,
]);
const handleChooseDownloadsPath = async () => {
@@ -194,8 +191,6 @@ export function DownloadSettingsModal({
const shouldDisableButton =
(downloader === Downloader.RealDebrid &&
!userPreferences?.realDebridApiToken) ||
(downloader === Downloader.AllDebrid &&
!userPreferences?.allDebridApiKey) ||
(downloader === Downloader.TorBox &&
!userPreferences?.torBoxApiToken) ||
(downloader === Downloader.Hydra &&

View File

@@ -1,12 +0,0 @@
.settings-all-debrid {
&__form {
display: flex;
flex-direction: column;
gap: 1rem;
}
&__description {
margin: 0;
color: var(--text-secondary);
}
}

View File

@@ -1,129 +0,0 @@
import { useContext, useEffect, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { Button, CheckboxField, Link, TextField } from "@renderer/components";
import "./settings-all-debrid.scss";
import { useAppSelector, useToast } from "@renderer/hooks";
import { settingsContext } from "@renderer/context";
const ALL_DEBRID_API_TOKEN_URL = "https://alldebrid.com/apikeys";
export function SettingsAllDebrid() {
const userPreferences = useAppSelector(
(state) => state.userPreferences.value
);
const { updateUserPreferences } = useContext(settingsContext);
const [isLoading, setIsLoading] = useState(false);
const [form, setForm] = useState({
useAllDebrid: false,
allDebridApiKey: null as string | null,
});
const { showSuccessToast, showErrorToast } = useToast();
const { t } = useTranslation("settings");
useEffect(() => {
if (userPreferences) {
setForm({
useAllDebrid: Boolean(userPreferences.allDebridApiKey),
allDebridApiKey: userPreferences.allDebridApiKey ?? null,
});
}
}, [userPreferences]);
const handleFormSubmit: React.FormEventHandler<HTMLFormElement> = async (
event
) => {
setIsLoading(true);
event.preventDefault();
try {
if (form.useAllDebrid) {
if (!form.allDebridApiKey) {
showErrorToast(t("alldebrid_missing_key"));
return;
}
const result = await window.electron.authenticateAllDebrid(
form.allDebridApiKey
);
if ("error_code" in result) {
showErrorToast(t(result.error_code));
return;
}
if (!result.isPremium) {
showErrorToast(
t("all_debrid_free_account_error", { username: result.username })
);
return;
}
showSuccessToast(
t("all_debrid_account_linked"),
t("debrid_linked_message", { username: result.username })
);
} else {
showSuccessToast(t("changes_saved"));
}
updateUserPreferences({
allDebridApiKey: form.useAllDebrid ? form.allDebridApiKey : null,
});
} catch (err: any) {
showErrorToast(t("alldebrid_unknown_error"));
} finally {
setIsLoading(false);
}
};
const isButtonDisabled =
(form.useAllDebrid && !form.allDebridApiKey) || isLoading;
return (
<form className="settings-all-debrid__form" onSubmit={handleFormSubmit}>
<p className="settings-all-debrid__description">
{t("all_debrid_description")}
</p>
<CheckboxField
label={t("enable_all_debrid")}
checked={form.useAllDebrid}
onChange={() =>
setForm((prev) => ({
...prev,
useAllDebrid: !form.useAllDebrid,
}))
}
/>
{form.useAllDebrid && (
<TextField
label={t("api_token")}
value={form.allDebridApiKey ?? ""}
type="password"
onChange={(event) =>
setForm({ ...form, allDebridApiKey: event.target.value })
}
rightContent={
<Button type="submit" disabled={isButtonDisabled}>
{t("save_changes")}
</Button>
}
placeholder="API Key"
hint={
<Trans i18nKey="debrid_api_token_hint" ns="settings">
<Link to={ALL_DEBRID_API_TOKEN_URL} />
</Trans>
}
/>
)}
</form>
);
}

View File

@@ -2,7 +2,6 @@ import { useState, useCallback, useMemo } from "react";
import { useFeature, useAppSelector } from "@renderer/hooks";
import { SettingsTorBox } from "./settings-torbox";
import { SettingsRealDebrid } from "./settings-real-debrid";
import { SettingsAllDebrid } from "./settings-all-debrid";
import { motion, AnimatePresence } from "framer-motion";
import { ChevronRightIcon, CheckCircleFillIcon } from "@primer/octicons-react";
import { useTranslation } from "react-i18next";
@@ -11,7 +10,6 @@ import "./settings-debrid.scss";
interface CollapseState {
torbox: boolean;
realDebrid: boolean;
allDebrid: boolean;
}
const sectionVariants = {
@@ -71,7 +69,6 @@ export function SettingsDebrid() {
return {
torbox: !userPreferences?.torBoxApiToken,
realDebrid: !userPreferences?.realDebridApiToken,
allDebrid: !userPreferences?.allDebridApiKey,
};
}, [userPreferences]);
@@ -178,51 +175,6 @@ export function SettingsDebrid() {
</AnimatePresence>
</div>
)}
<div className="settings-debrid__section">
<div className="settings-debrid__section-header">
<button
type="button"
className="settings-debrid__collapse-button"
onClick={() => toggleSection("allDebrid")}
aria-label={
collapseState.allDebrid
? "Expand All-Debrid section"
: "Collapse All-Debrid section"
}
>
<motion.div
variants={chevronVariants}
animate={collapseState.allDebrid ? "collapsed" : "expanded"}
>
<ChevronRightIcon size={16} />
</motion.div>
</button>
<h3 className="settings-debrid__section-title">All-Debrid</h3>
<span className="settings-debrid__beta-badge">BETA</span>
{userPreferences?.allDebridApiKey && (
<CheckCircleFillIcon
size={16}
className="settings-debrid__check-icon"
/>
)}
</div>
<AnimatePresence initial={true} mode="wait">
{!collapseState.allDebrid && (
<motion.div
key="alldebrid-content"
variants={sectionVariants}
initial="collapsed"
animate="expanded"
exit="collapsed"
layout
>
<SettingsAllDebrid />
</motion.div>
)}
</AnimatePresence>
</div>
</div>
);
}