Merge branch 'main' into feat/context_game_menu

This commit is contained in:
Chubby Granny Chaser
2025-10-02 10:50:13 +01:00
committed by GitHub
25 changed files with 793 additions and 18 deletions

View File

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

View File

@@ -9,6 +9,7 @@ import type {
UserPreferences,
StartGameDownloadPayload,
RealDebridUser,
AllDebridUser,
UserProfile,
FriendRequest,
FriendRequestAction,
@@ -212,6 +213,9 @@ 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,6 +114,15 @@ 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>;
@@ -181,6 +190,15 @@ 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>
@@ -275,7 +293,9 @@ export function DownloadGroup({
(download?.downloader === Downloader.RealDebrid &&
!userPreferences?.realDebridApiToken) ||
(download?.downloader === Downloader.TorBox &&
!userPreferences?.torBoxApiToken);
!userPreferences?.torBoxApiToken) ||
(download?.downloader === Downloader.AllDebrid &&
!userPreferences?.allDebridApiKey);
return [
{

View File

@@ -117,6 +117,8 @@ 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;
@@ -131,6 +133,7 @@ export function DownloadSettingsModal({
downloaders,
userPreferences?.realDebridApiToken,
userPreferences?.torBoxApiToken,
userPreferences?.allDebridApiKey,
]);
const handleChooseDownloadsPath = async () => {
@@ -191,6 +194,8 @@ 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

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

View File

@@ -0,0 +1,129 @@
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

@@ -1,6 +1,7 @@
import { Button } from "@renderer/components";
import { useTranslation } from "react-i18next";
import { SettingsRealDebrid } from "./settings-real-debrid";
import { SettingsAllDebrid } from "./settings-all-debrid";
import { SettingsGeneral } from "./settings-general";
import { SettingsBehavior } from "./settings-behavior";
import { SettingsDownloadSources } from "./settings-download-sources";
@@ -42,6 +43,7 @@ export default function Settings() {
]
: []),
{ tabLabel: "Real-Debrid", contentTitle: "Real-Debrid" },
{ tabLabel: "All-Debrid", contentTitle: "All-Debrid" },
];
if (userDetails)
@@ -81,6 +83,10 @@ export default function Settings() {
return <SettingsRealDebrid />;
}
if (currentCategoryIndex === 6) {
return <SettingsAllDebrid />;
}
return <SettingsAccount />;
};