mirror of
https://github.com/p-stream/p-stream.git
synced 2026-04-21 05:02:24 +00:00
add all preferences and fix
fixed febbox token account sync and add every other preference (except subtitle) to the backend sync
This commit is contained in:
parent
b1fdc56a0a
commit
52aa105aed
11 changed files with 238 additions and 81 deletions
|
|
@ -9,6 +9,17 @@ export interface SettingsInput {
|
||||||
defaultSubtitleLanguage?: string;
|
defaultSubtitleLanguage?: string;
|
||||||
proxyUrls?: string[] | null;
|
proxyUrls?: string[] | null;
|
||||||
febboxKey?: string | null;
|
febboxKey?: string | null;
|
||||||
|
enableThumbnails?: boolean;
|
||||||
|
enableAutoplay?: boolean;
|
||||||
|
enableSkipCredits?: boolean;
|
||||||
|
enableDiscover?: boolean;
|
||||||
|
enableFeatured?: boolean;
|
||||||
|
enableDetailsModal?: boolean;
|
||||||
|
enableImageLogos?: boolean;
|
||||||
|
enableCarouselView?: boolean;
|
||||||
|
sourceOrder?: string[];
|
||||||
|
enableSourceOrder?: boolean;
|
||||||
|
proxyTmdb?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SettingsResponse {
|
export interface SettingsResponse {
|
||||||
|
|
@ -17,6 +28,17 @@ export interface SettingsResponse {
|
||||||
defaultSubtitleLanguage?: string | null;
|
defaultSubtitleLanguage?: string | null;
|
||||||
proxyUrls?: string[] | null;
|
proxyUrls?: string[] | null;
|
||||||
febboxKey?: string | null;
|
febboxKey?: string | null;
|
||||||
|
enableThumbnails?: boolean;
|
||||||
|
enableAutoplay?: boolean;
|
||||||
|
enableSkipCredits?: boolean;
|
||||||
|
enableDiscover?: boolean;
|
||||||
|
enableFeatured?: boolean;
|
||||||
|
enableDetailsModal?: boolean;
|
||||||
|
enableImageLogos?: boolean;
|
||||||
|
enableCarouselView?: boolean;
|
||||||
|
sourceOrder?: string[];
|
||||||
|
enableSourceOrder?: boolean;
|
||||||
|
proxyTmdb?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateSettings(
|
export function updateSettings(
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
|
||||||
|
|
||||||
import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta";
|
import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta";
|
||||||
import { conf } from "@/setup/config";
|
import { conf } from "@/setup/config";
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { usePreferencesStore } from "@/stores/preferences";
|
||||||
|
|
||||||
// Thanks Nemo for this API
|
// Thanks Nemo for this API
|
||||||
const BASE_URL = "https://skips.pstream.org";
|
const BASE_URL = "https://skips.pstream.org";
|
||||||
|
|
@ -11,13 +11,13 @@ const MAX_RETRIES = 3;
|
||||||
export function useSkipTime() {
|
export function useSkipTime() {
|
||||||
const { playerMeta: meta } = usePlayerMeta();
|
const { playerMeta: meta } = usePlayerMeta();
|
||||||
const [skiptime, setSkiptime] = useState<number | null>(null);
|
const [skiptime, setSkiptime] = useState<number | null>(null);
|
||||||
const febboxToken = useAuthStore((s) => s.febboxToken);
|
const febboxKey = usePreferencesStore((s) => s.febboxKey);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchSkipTime = async (retries = 0): Promise<void> => {
|
const fetchSkipTime = async (retries = 0): Promise<void> => {
|
||||||
if (!meta?.imdbId || meta.type === "movie") return;
|
if (!meta?.imdbId || meta.type === "movie") return;
|
||||||
if (!conf().ALLOW_FEBBOX_KEY) return;
|
if (!conf().ALLOW_FEBBOX_KEY) return;
|
||||||
if (!febboxToken) return;
|
if (!febboxKey) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const apiUrl = `${BASE_URL}/${meta.imdbId}/${meta.season?.number}/${meta.episode?.number}`;
|
const apiUrl = `${BASE_URL}/${meta.imdbId}/${meta.season?.number}/${meta.episode?.number}`;
|
||||||
|
|
@ -57,7 +57,7 @@ export function useSkipTime() {
|
||||||
meta?.type,
|
meta?.type,
|
||||||
meta?.season?.number,
|
meta?.season?.number,
|
||||||
meta?.episode?.number,
|
meta?.episode?.number,
|
||||||
febboxToken,
|
febboxKey,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return skiptime;
|
return skiptime;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import {
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { useAuthStore } from "@/stores/auth";
|
||||||
import { useBookmarkStore } from "@/stores/bookmarks";
|
import { useBookmarkStore } from "@/stores/bookmarks";
|
||||||
import { useLanguageStore } from "@/stores/language";
|
import { useLanguageStore } from "@/stores/language";
|
||||||
|
import { usePreferencesStore } from "@/stores/preferences";
|
||||||
import { useProgressStore } from "@/stores/progress";
|
import { useProgressStore } from "@/stores/progress";
|
||||||
import { useSubtitleStore } from "@/stores/subtitles";
|
import { useSubtitleStore } from "@/stores/subtitles";
|
||||||
import { useThemeStore } from "@/stores/theme";
|
import { useThemeStore } from "@/stores/theme";
|
||||||
|
|
@ -28,11 +29,31 @@ export function useAuthData() {
|
||||||
const importSubtitleLanguage = useSubtitleStore(
|
const importSubtitleLanguage = useSubtitleStore(
|
||||||
(s) => s.importSubtitleLanguage,
|
(s) => s.importSubtitleLanguage,
|
||||||
);
|
);
|
||||||
const setFebboxToken = useAuthStore((s) => s.setFebboxToken);
|
const setFebboxKey = usePreferencesStore((s) => s.setFebboxKey);
|
||||||
|
|
||||||
const replaceBookmarks = useBookmarkStore((s) => s.replaceBookmarks);
|
const replaceBookmarks = useBookmarkStore((s) => s.replaceBookmarks);
|
||||||
const replaceItems = useProgressStore((s) => s.replaceItems);
|
const replaceItems = useProgressStore((s) => s.replaceItems);
|
||||||
|
|
||||||
|
const setEnableThumbnails = usePreferencesStore((s) => s.setEnableThumbnails);
|
||||||
|
const setEnableAutoplay = usePreferencesStore((s) => s.setEnableAutoplay);
|
||||||
|
const setEnableSkipCredits = usePreferencesStore(
|
||||||
|
(s) => s.setEnableSkipCredits,
|
||||||
|
);
|
||||||
|
const setEnableDiscover = usePreferencesStore((s) => s.setEnableDiscover);
|
||||||
|
const setEnableFeatured = usePreferencesStore((s) => s.setEnableFeatured);
|
||||||
|
const setEnableDetailsModal = usePreferencesStore(
|
||||||
|
(s) => s.setEnableDetailsModal,
|
||||||
|
);
|
||||||
|
const setEnableImageLogos = usePreferencesStore((s) => s.setEnableImageLogos);
|
||||||
|
const setEnableCarouselView = usePreferencesStore(
|
||||||
|
(s) => s.setEnableCarouselView,
|
||||||
|
);
|
||||||
|
const setSourceOrder = usePreferencesStore((s) => s.setSourceOrder);
|
||||||
|
const setEnableSourceOrder = usePreferencesStore(
|
||||||
|
(s) => s.setEnableSourceOrder,
|
||||||
|
);
|
||||||
|
const setProxyTmdb = usePreferencesStore((s) => s.setProxyTmdb);
|
||||||
|
|
||||||
const login = useCallback(
|
const login = useCallback(
|
||||||
async (
|
async (
|
||||||
loginResponse: LoginResponse,
|
loginResponse: LoginResponse,
|
||||||
|
|
@ -58,8 +79,8 @@ export function useAuthData() {
|
||||||
removeAccount();
|
removeAccount();
|
||||||
clearBookmarks();
|
clearBookmarks();
|
||||||
clearProgress();
|
clearProgress();
|
||||||
setFebboxToken(null);
|
setFebboxKey(null);
|
||||||
}, [removeAccount, clearBookmarks, clearProgress, setFebboxToken]);
|
}, [removeAccount, clearBookmarks, clearProgress, setFebboxKey]);
|
||||||
|
|
||||||
const syncData = useCallback(
|
const syncData = useCallback(
|
||||||
async (
|
async (
|
||||||
|
|
@ -87,6 +108,54 @@ export function useAuthData() {
|
||||||
if (settings.proxyUrls) {
|
if (settings.proxyUrls) {
|
||||||
setProxySet(settings.proxyUrls);
|
setProxySet(settings.proxyUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.enableThumbnails !== undefined) {
|
||||||
|
setEnableThumbnails(settings.enableThumbnails);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.enableAutoplay !== undefined) {
|
||||||
|
setEnableAutoplay(settings.enableAutoplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.enableSkipCredits !== undefined) {
|
||||||
|
setEnableSkipCredits(settings.enableSkipCredits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.enableDiscover !== undefined) {
|
||||||
|
setEnableDiscover(settings.enableDiscover);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.enableFeatured !== undefined) {
|
||||||
|
setEnableFeatured(settings.enableFeatured);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.enableDetailsModal !== undefined) {
|
||||||
|
setEnableDetailsModal(settings.enableDetailsModal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.enableImageLogos !== undefined) {
|
||||||
|
setEnableImageLogos(settings.enableImageLogos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.enableCarouselView !== undefined) {
|
||||||
|
setEnableCarouselView(settings.enableCarouselView);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.sourceOrder !== undefined) {
|
||||||
|
setSourceOrder(settings.sourceOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.enableSourceOrder !== undefined) {
|
||||||
|
setEnableSourceOrder(settings.enableSourceOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.proxyTmdb !== undefined) {
|
||||||
|
setProxyTmdb(settings.proxyTmdb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.febboxKey !== undefined) {
|
||||||
|
setFebboxKey(settings.febboxKey);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
replaceBookmarks,
|
replaceBookmarks,
|
||||||
|
|
@ -95,6 +164,18 @@ export function useAuthData() {
|
||||||
importSubtitleLanguage,
|
importSubtitleLanguage,
|
||||||
setTheme,
|
setTheme,
|
||||||
setProxySet,
|
setProxySet,
|
||||||
|
setEnableThumbnails,
|
||||||
|
setEnableAutoplay,
|
||||||
|
setEnableSkipCredits,
|
||||||
|
setEnableDiscover,
|
||||||
|
setEnableFeatured,
|
||||||
|
setEnableDetailsModal,
|
||||||
|
setEnableImageLogos,
|
||||||
|
setEnableCarouselView,
|
||||||
|
setSourceOrder,
|
||||||
|
setEnableSourceOrder,
|
||||||
|
setProxyTmdb,
|
||||||
|
setFebboxKey,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ export function useSettingsState(
|
||||||
deviceName: string,
|
deviceName: string,
|
||||||
proxyUrls: string[] | null,
|
proxyUrls: string[] | null,
|
||||||
backendUrl: string | null,
|
backendUrl: string | null,
|
||||||
febboxToken: string | null,
|
febboxKey: string | null,
|
||||||
profile:
|
profile:
|
||||||
| {
|
| {
|
||||||
colorA: string;
|
colorA: string;
|
||||||
|
|
@ -67,12 +67,8 @@ export function useSettingsState(
|
||||||
useDerived(proxyUrls);
|
useDerived(proxyUrls);
|
||||||
const [backendUrlState, setBackendUrl, resetBackendUrl, backendUrlChanged] =
|
const [backendUrlState, setBackendUrl, resetBackendUrl, backendUrlChanged] =
|
||||||
useDerived(backendUrl);
|
useDerived(backendUrl);
|
||||||
const [
|
const [febboxKeyState, setFebboxKey, resetFebboxKey, febboxKeyChanged] =
|
||||||
febboxTokenState,
|
useDerived(febboxKey);
|
||||||
setFebboxToken,
|
|
||||||
resetFebboxToken,
|
|
||||||
febboxTokenChanged,
|
|
||||||
] = useDerived(febboxToken);
|
|
||||||
const [themeState, setTheme, resetTheme, themeChanged] = useDerived(theme);
|
const [themeState, setTheme, resetTheme, themeChanged] = useDerived(theme);
|
||||||
const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme);
|
const setPreviewTheme = usePreviewThemeStore((s) => s.setPreviewTheme);
|
||||||
const resetPreviewTheme = useCallback(
|
const resetPreviewTheme = useCallback(
|
||||||
|
|
@ -165,7 +161,7 @@ export function useSettingsState(
|
||||||
resetSubStyling();
|
resetSubStyling();
|
||||||
resetProxyUrls();
|
resetProxyUrls();
|
||||||
resetBackendUrl();
|
resetBackendUrl();
|
||||||
resetFebboxToken();
|
resetFebboxKey();
|
||||||
resetDeviceName();
|
resetDeviceName();
|
||||||
resetProfile();
|
resetProfile();
|
||||||
resetEnableThumbnails();
|
resetEnableThumbnails();
|
||||||
|
|
@ -188,7 +184,7 @@ export function useSettingsState(
|
||||||
deviceNameChanged ||
|
deviceNameChanged ||
|
||||||
backendUrlChanged ||
|
backendUrlChanged ||
|
||||||
proxyUrlsChanged ||
|
proxyUrlsChanged ||
|
||||||
febboxTokenChanged ||
|
febboxKeyChanged ||
|
||||||
profileChanged ||
|
profileChanged ||
|
||||||
enableThumbnailsChanged ||
|
enableThumbnailsChanged ||
|
||||||
enableAutoplayChanged ||
|
enableAutoplayChanged ||
|
||||||
|
|
@ -235,10 +231,10 @@ export function useSettingsState(
|
||||||
set: setBackendUrl,
|
set: setBackendUrl,
|
||||||
changed: backendUrlChanged,
|
changed: backendUrlChanged,
|
||||||
},
|
},
|
||||||
febboxToken: {
|
febboxKey: {
|
||||||
state: febboxTokenState,
|
state: febboxKeyState,
|
||||||
set: setFebboxToken,
|
set: setFebboxKey,
|
||||||
changed: febboxTokenChanged,
|
changed: febboxKeyChanged,
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
state: profileState,
|
state: profileState,
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,8 @@ export function SettingsPage() {
|
||||||
const backendUrlSetting = useAuthStore((s) => s.backendUrl);
|
const backendUrlSetting = useAuthStore((s) => s.backendUrl);
|
||||||
const setBackendUrl = useAuthStore((s) => s.setBackendUrl);
|
const setBackendUrl = useAuthStore((s) => s.setBackendUrl);
|
||||||
|
|
||||||
const febboxToken = useAuthStore((s) => s.febboxToken);
|
const febboxKey = usePreferencesStore((s) => s.febboxKey);
|
||||||
const setFebboxToken = useAuthStore((s) => s.setFebboxToken);
|
const setFebboxKey = usePreferencesStore((s) => s.setFebboxKey);
|
||||||
|
|
||||||
const enableThumbnails = usePreferencesStore((s) => s.enableThumbnails);
|
const enableThumbnails = usePreferencesStore((s) => s.enableThumbnails);
|
||||||
const setEnableThumbnails = usePreferencesStore((s) => s.setEnableThumbnails);
|
const setEnableThumbnails = usePreferencesStore((s) => s.setEnableThumbnails);
|
||||||
|
|
@ -193,12 +193,12 @@ export function SettingsPage() {
|
||||||
if (account && backendUrl) {
|
if (account && backendUrl) {
|
||||||
const settings = await getSettings(backendUrl, account);
|
const settings = await getSettings(backendUrl, account);
|
||||||
if (settings.febboxKey) {
|
if (settings.febboxKey) {
|
||||||
setFebboxToken(settings.febboxKey);
|
setFebboxKey(settings.febboxKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
loadSettings();
|
loadSettings();
|
||||||
}, [account, backendUrl, setFebboxToken]);
|
}, [account, backendUrl, setFebboxKey]);
|
||||||
|
|
||||||
const state = useSettingsState(
|
const state = useSettingsState(
|
||||||
activeTheme,
|
activeTheme,
|
||||||
|
|
@ -207,7 +207,7 @@ export function SettingsPage() {
|
||||||
decryptedName,
|
decryptedName,
|
||||||
proxySet,
|
proxySet,
|
||||||
backendUrlSetting,
|
backendUrlSetting,
|
||||||
febboxToken,
|
febboxKey,
|
||||||
account ? account.profile : undefined,
|
account ? account.profile : undefined,
|
||||||
enableThumbnails,
|
enableThumbnails,
|
||||||
enableAutoplay,
|
enableAutoplay,
|
||||||
|
|
@ -263,13 +263,35 @@ export function SettingsPage() {
|
||||||
state.appLanguage.changed ||
|
state.appLanguage.changed ||
|
||||||
state.theme.changed ||
|
state.theme.changed ||
|
||||||
state.proxyUrls.changed ||
|
state.proxyUrls.changed ||
|
||||||
state.febboxToken.changed
|
state.febboxKey.changed ||
|
||||||
|
state.enableThumbnails.changed ||
|
||||||
|
state.enableAutoplay.changed ||
|
||||||
|
state.enableSkipCredits.changed ||
|
||||||
|
state.enableDiscover.changed ||
|
||||||
|
state.enableFeatured.changed ||
|
||||||
|
state.enableDetailsModal.changed ||
|
||||||
|
state.enableImageLogos.changed ||
|
||||||
|
state.sourceOrder.changed ||
|
||||||
|
state.enableSourceOrder.changed ||
|
||||||
|
state.proxyTmdb.changed ||
|
||||||
|
state.enableCarouselView.changed
|
||||||
) {
|
) {
|
||||||
await updateSettings(backendUrl, account, {
|
await updateSettings(backendUrl, account, {
|
||||||
applicationLanguage: state.appLanguage.state,
|
applicationLanguage: state.appLanguage.state,
|
||||||
applicationTheme: state.theme.state,
|
applicationTheme: state.theme.state,
|
||||||
proxyUrls: state.proxyUrls.state?.filter((v) => v !== "") ?? null,
|
proxyUrls: state.proxyUrls.state?.filter((v) => v !== "") ?? null,
|
||||||
febboxKey: state.febboxToken.state,
|
febboxKey: state.febboxKey.state,
|
||||||
|
enableThumbnails: state.enableThumbnails.state,
|
||||||
|
enableAutoplay: state.enableAutoplay.state,
|
||||||
|
enableSkipCredits: state.enableSkipCredits.state,
|
||||||
|
enableDiscover: state.enableDiscover.state,
|
||||||
|
enableFeatured: state.enableFeatured.state,
|
||||||
|
enableDetailsModal: state.enableDetailsModal.state,
|
||||||
|
enableImageLogos: state.enableImageLogos.state,
|
||||||
|
sourceOrder: state.sourceOrder.state,
|
||||||
|
enableSourceOrder: state.enableSourceOrder.state,
|
||||||
|
proxyTmdb: state.proxyTmdb.state,
|
||||||
|
enableCarouselView: state.enableCarouselView.state,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (state.deviceName.changed) {
|
if (state.deviceName.changed) {
|
||||||
|
|
@ -302,7 +324,7 @@ export function SettingsPage() {
|
||||||
setSubStyling(state.subtitleStyling.state);
|
setSubStyling(state.subtitleStyling.state);
|
||||||
setProxySet(state.proxyUrls.state?.filter((v) => v !== "") ?? null);
|
setProxySet(state.proxyUrls.state?.filter((v) => v !== "") ?? null);
|
||||||
setEnableSourceOrder(state.enableSourceOrder.state);
|
setEnableSourceOrder(state.enableSourceOrder.state);
|
||||||
setFebboxToken(state.febboxToken.state);
|
setFebboxKey(state.febboxKey.state);
|
||||||
setProxyTmdb(state.proxyTmdb.state);
|
setProxyTmdb(state.proxyTmdb.state);
|
||||||
setEnableCarouselView(state.enableCarouselView.state);
|
setEnableCarouselView(state.enableCarouselView.state);
|
||||||
|
|
||||||
|
|
@ -325,7 +347,7 @@ export function SettingsPage() {
|
||||||
account,
|
account,
|
||||||
backendUrl,
|
backendUrl,
|
||||||
setEnableThumbnails,
|
setEnableThumbnails,
|
||||||
setFebboxToken,
|
setFebboxKey,
|
||||||
state,
|
state,
|
||||||
setEnableAutoplay,
|
setEnableAutoplay,
|
||||||
setEnableSkipCredits,
|
setEnableSkipCredits,
|
||||||
|
|
@ -424,8 +446,8 @@ export function SettingsPage() {
|
||||||
setBackendUrl={state.backendUrl.set}
|
setBackendUrl={state.backendUrl.set}
|
||||||
proxyUrls={state.proxyUrls.state}
|
proxyUrls={state.proxyUrls.state}
|
||||||
setProxyUrls={state.proxyUrls.set}
|
setProxyUrls={state.proxyUrls.set}
|
||||||
febboxToken={state.febboxToken.state}
|
febboxKey={state.febboxKey.state}
|
||||||
setFebboxToken={state.febboxToken.set}
|
setFebboxKey={state.febboxKey.set}
|
||||||
proxyTmdb={state.proxyTmdb.state}
|
proxyTmdb={state.proxyTmdb.state}
|
||||||
setProxyTmdb={state.proxyTmdb.set}
|
setProxyTmdb={state.proxyTmdb.set}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,14 @@ import {
|
||||||
import { PageTitle } from "@/pages/parts/util/PageTitle";
|
import { PageTitle } from "@/pages/parts/util/PageTitle";
|
||||||
import { conf } from "@/setup/config";
|
import { conf } from "@/setup/config";
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
import { usePreferencesStore } from "@/stores/preferences";
|
||||||
import { getProxyUrls } from "@/utils/proxyUrls";
|
import { getProxyUrls } from "@/utils/proxyUrls";
|
||||||
|
|
||||||
import { Status, testFebboxToken } from "../parts/settings/SetupPart";
|
import { Status, testFebboxKey } from "../parts/settings/SetupPart";
|
||||||
|
|
||||||
async function getFebboxTokenStatus(febboxToken: string | null) {
|
async function getFebboxKeyStatus(febboxKey: string | null) {
|
||||||
if (febboxToken) {
|
if (febboxKey) {
|
||||||
const status: Status = await testFebboxToken(febboxToken);
|
const status: Status = await testFebboxKey(febboxKey);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
return "unset";
|
return "unset";
|
||||||
|
|
@ -57,8 +58,17 @@ async function getFebboxTokenStatus(febboxToken: string | null) {
|
||||||
export function FEDAPISetup() {
|
export function FEDAPISetup() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [isExpanded, setIsExpanded] = useState(false);
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
const febboxToken = useAuthStore((s) => s.febboxToken);
|
const febboxKey = usePreferencesStore((s) => s.febboxKey);
|
||||||
const setFebboxToken = useAuthStore((s) => s.setFebboxToken);
|
const setFebboxKey = usePreferencesStore((s) => s.setFebboxKey);
|
||||||
|
const user = useAuthStore();
|
||||||
|
|
||||||
|
// Enable febbox token when account is loaded and we have a token
|
||||||
|
useEffect(() => {
|
||||||
|
if (user.account && febboxKey) {
|
||||||
|
setFebboxKey(febboxKey);
|
||||||
|
setIsExpanded(true);
|
||||||
|
}
|
||||||
|
}, [user.account, febboxKey, setFebboxKey]);
|
||||||
|
|
||||||
const [status, setStatus] = useState<Status>("unset");
|
const [status, setStatus] = useState<Status>("unset");
|
||||||
const statusMap: Record<Status, StatusCircleProps["type"]> = {
|
const statusMap: Record<Status, StatusCircleProps["type"]> = {
|
||||||
|
|
@ -71,11 +81,11 @@ export function FEDAPISetup() {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkTokenStatus = async () => {
|
const checkTokenStatus = async () => {
|
||||||
const result = await getFebboxTokenStatus(febboxToken);
|
const result = await getFebboxKeyStatus(febboxKey);
|
||||||
setStatus(result);
|
setStatus(result);
|
||||||
};
|
};
|
||||||
checkTokenStatus();
|
checkTokenStatus();
|
||||||
}, [febboxToken]);
|
}, [febboxKey]);
|
||||||
|
|
||||||
const [showVideo, setShowVideo] = useState(false);
|
const [showVideo, setShowVideo] = useState(false);
|
||||||
|
|
||||||
|
|
@ -161,9 +171,9 @@ export function FEDAPISetup() {
|
||||||
<StatusCircle type={statusMap[status]} className="mx-2 mr-4" />
|
<StatusCircle type={statusMap[status]} className="mx-2 mr-4" />
|
||||||
<AuthInputBox
|
<AuthInputBox
|
||||||
onChange={(newToken) => {
|
onChange={(newToken) => {
|
||||||
setFebboxToken(newToken);
|
setFebboxKey(newToken);
|
||||||
}}
|
}}
|
||||||
value={febboxToken ?? ""}
|
value={febboxKey ?? ""}
|
||||||
placeholder="eyABCdE..."
|
placeholder="eyABCdE..."
|
||||||
passwordToggleable
|
passwordToggleable
|
||||||
className="flex-grow"
|
className="flex-grow"
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import { useBackendUrl } from "@/hooks/auth/useBackendUrl";
|
||||||
import { AccountProfile } from "@/pages/parts/auth/AccountCreatePart";
|
import { AccountProfile } from "@/pages/parts/auth/AccountCreatePart";
|
||||||
import { useBookmarkStore } from "@/stores/bookmarks";
|
import { useBookmarkStore } from "@/stores/bookmarks";
|
||||||
import { useLanguageStore } from "@/stores/language";
|
import { useLanguageStore } from "@/stores/language";
|
||||||
|
import { usePreferencesStore } from "@/stores/preferences";
|
||||||
import { useProgressStore } from "@/stores/progress";
|
import { useProgressStore } from "@/stores/progress";
|
||||||
import { useSubtitleStore } from "@/stores/subtitles";
|
import { useSubtitleStore } from "@/stores/subtitles";
|
||||||
import { useThemeStore } from "@/stores/theme";
|
import { useThemeStore } from "@/stores/theme";
|
||||||
|
|
@ -40,6 +41,21 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
|
||||||
);
|
);
|
||||||
const applicationTheme = useThemeStore((store) => store.theme);
|
const applicationTheme = useThemeStore((store) => store.theme);
|
||||||
|
|
||||||
|
const preferences = usePreferencesStore((store) => ({
|
||||||
|
enableThumbnails: store.enableThumbnails,
|
||||||
|
enableAutoplay: store.enableAutoplay,
|
||||||
|
enableSkipCredits: store.enableSkipCredits,
|
||||||
|
enableDiscover: store.enableDiscover,
|
||||||
|
enableFeatured: store.enableFeatured,
|
||||||
|
enableDetailsModal: store.enableDetailsModal,
|
||||||
|
enableImageLogos: store.enableImageLogos,
|
||||||
|
enableCarouselView: store.enableCarouselView,
|
||||||
|
sourceOrder: store.sourceOrder,
|
||||||
|
enableSourceOrder: store.enableSourceOrder,
|
||||||
|
proxyTmdb: store.proxyTmdb,
|
||||||
|
febboxKey: store.febboxKey,
|
||||||
|
}));
|
||||||
|
|
||||||
const backendUrl = useBackendUrl();
|
const backendUrl = useBackendUrl();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|
@ -80,6 +96,7 @@ export function VerifyPassphrase(props: VerifyPassphraseProps) {
|
||||||
defaultSubtitleLanguage: defaultSubtitleLanguage ?? undefined,
|
defaultSubtitleLanguage: defaultSubtitleLanguage ?? undefined,
|
||||||
applicationTheme: applicationTheme ?? undefined,
|
applicationTheme: applicationTheme ?? undefined,
|
||||||
proxyUrls: undefined,
|
proxyUrls: undefined,
|
||||||
|
...preferences,
|
||||||
});
|
});
|
||||||
|
|
||||||
await restore(account);
|
await restore(account);
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,11 @@ import { Heading1 } from "@/components/utils/Text";
|
||||||
import {
|
import {
|
||||||
SetupPart,
|
SetupPart,
|
||||||
Status,
|
Status,
|
||||||
testFebboxToken,
|
testFebboxKey,
|
||||||
} from "@/pages/parts/settings/SetupPart";
|
} from "@/pages/parts/settings/SetupPart";
|
||||||
import { conf } from "@/setup/config";
|
import { conf } from "@/setup/config";
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
import { usePreferencesStore } from "@/stores/preferences";
|
||||||
|
|
||||||
interface ProxyEditProps {
|
interface ProxyEditProps {
|
||||||
proxyUrls: string[] | null;
|
proxyUrls: string[] | null;
|
||||||
|
|
@ -39,9 +40,9 @@ interface BackendEditProps {
|
||||||
setBackendUrl: Dispatch<SetStateAction<string | null>>;
|
setBackendUrl: Dispatch<SetStateAction<string | null>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FebboxTokenProps {
|
interface FebboxKeyProps {
|
||||||
febboxToken: string | null;
|
febboxKey: string | null;
|
||||||
setFebboxToken: Dispatch<SetStateAction<string | null>>;
|
setFebboxKey: Dispatch<SetStateAction<string | null>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ProxyEdit({
|
function ProxyEdit({
|
||||||
|
|
@ -218,17 +219,26 @@ function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getFebboxTokenStatus(febboxToken: string | null) {
|
async function getFebboxKeyStatus(febboxKey: string | null) {
|
||||||
if (febboxToken) {
|
if (febboxKey) {
|
||||||
const status: Status = await testFebboxToken(febboxToken);
|
const status: Status = await testFebboxKey(febboxKey);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
return "unset";
|
return "unset";
|
||||||
}
|
}
|
||||||
|
|
||||||
function FebboxTokenEdit({ febboxToken, setFebboxToken }: FebboxTokenProps) {
|
function FebboxKeyEdit({ febboxKey, setFebboxKey }: FebboxKeyProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [showVideo, setShowVideo] = useState(false);
|
const [showVideo, setShowVideo] = useState(false);
|
||||||
|
const user = useAuthStore();
|
||||||
|
const preferences = usePreferencesStore();
|
||||||
|
|
||||||
|
// Enable febbox token when account is loaded and we have a token
|
||||||
|
useEffect(() => {
|
||||||
|
if (user.account && febboxKey === null && preferences.febboxKey) {
|
||||||
|
setFebboxKey(preferences.febboxKey);
|
||||||
|
}
|
||||||
|
}, [user.account, febboxKey, preferences.febboxKey, setFebboxKey]);
|
||||||
|
|
||||||
const [status, setStatus] = useState<Status>("unset");
|
const [status, setStatus] = useState<Status>("unset");
|
||||||
const statusMap: Record<Status, StatusCircleProps["type"]> = {
|
const statusMap: Record<Status, StatusCircleProps["type"]> = {
|
||||||
|
|
@ -241,11 +251,11 @@ function FebboxTokenEdit({ febboxToken, setFebboxToken }: FebboxTokenProps) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkTokenStatus = async () => {
|
const checkTokenStatus = async () => {
|
||||||
const result = await getFebboxTokenStatus(febboxToken);
|
const result = await getFebboxKeyStatus(febboxKey);
|
||||||
setStatus(result);
|
setStatus(result);
|
||||||
};
|
};
|
||||||
checkTokenStatus();
|
checkTokenStatus();
|
||||||
}, [febboxToken]);
|
}, [febboxKey]);
|
||||||
|
|
||||||
if (conf().ALLOW_FEBBOX_KEY) {
|
if (conf().ALLOW_FEBBOX_KEY) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -261,12 +271,12 @@ function FebboxTokenEdit({ febboxToken, setFebboxToken }: FebboxTokenProps) {
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Toggle
|
<Toggle
|
||||||
onClick={() => setFebboxToken((s) => (s === null ? "" : null))}
|
onClick={() => setFebboxKey((s) => (s === null ? "" : null))}
|
||||||
enabled={febboxToken !== null}
|
enabled={febboxKey !== null}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{febboxToken !== null ? (
|
{febboxKey !== null ? (
|
||||||
<>
|
<>
|
||||||
<Divider marginClass="my-6 px-8 box-content -mx-8" />
|
<Divider marginClass="my-6 px-8 box-content -mx-8" />
|
||||||
|
|
||||||
|
|
@ -328,9 +338,9 @@ function FebboxTokenEdit({ febboxToken, setFebboxToken }: FebboxTokenProps) {
|
||||||
<StatusCircle type={statusMap[status]} className="mx-2 mr-4" />
|
<StatusCircle type={statusMap[status]} className="mx-2 mr-4" />
|
||||||
<AuthInputBox
|
<AuthInputBox
|
||||||
onChange={(newToken) => {
|
onChange={(newToken) => {
|
||||||
setFebboxToken(newToken);
|
setFebboxKey(newToken);
|
||||||
}}
|
}}
|
||||||
value={febboxToken ?? ""}
|
value={febboxKey ?? ""}
|
||||||
placeholder="eyABCdE..."
|
placeholder="eyABCdE..."
|
||||||
passwordToggleable
|
passwordToggleable
|
||||||
className="flex-grow"
|
className="flex-grow"
|
||||||
|
|
@ -359,7 +369,7 @@ function FebboxTokenEdit({ febboxToken, setFebboxToken }: FebboxTokenProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ConnectionsPart(
|
export function ConnectionsPart(
|
||||||
props: BackendEditProps & ProxyEditProps & FebboxTokenProps,
|
props: BackendEditProps & ProxyEditProps & FebboxKeyProps,
|
||||||
) {
|
) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
|
|
@ -377,9 +387,9 @@ export function ConnectionsPart(
|
||||||
backendUrl={props.backendUrl}
|
backendUrl={props.backendUrl}
|
||||||
setBackendUrl={props.setBackendUrl}
|
setBackendUrl={props.setBackendUrl}
|
||||||
/>
|
/>
|
||||||
<FebboxTokenEdit
|
<FebboxKeyEdit
|
||||||
febboxToken={props.febboxToken}
|
febboxKey={props.febboxKey}
|
||||||
setFebboxToken={props.setFebboxToken}
|
setFebboxKey={props.setFebboxKey}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import {
|
||||||
import { Heading3 } from "@/components/utils/Text";
|
import { Heading3 } from "@/components/utils/Text";
|
||||||
import { conf } from "@/setup/config";
|
import { conf } from "@/setup/config";
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
import { usePreferencesStore } from "@/stores/preferences";
|
||||||
|
|
||||||
const getRegion = async (): Promise<string | null> => {
|
const getRegion = async (): Promise<string | null> => {
|
||||||
if (typeof window === "undefined") return null;
|
if (typeof window === "undefined") return null;
|
||||||
|
|
@ -72,7 +73,7 @@ type SetupData = {
|
||||||
extension: Status;
|
extension: Status;
|
||||||
proxy: Status;
|
proxy: Status;
|
||||||
defaultProxy: Status;
|
defaultProxy: Status;
|
||||||
febboxTokenTest?: Status;
|
febboxKeyTest?: Status;
|
||||||
};
|
};
|
||||||
|
|
||||||
function testProxy(url: string) {
|
function testProxy(url: string) {
|
||||||
|
|
@ -87,13 +88,11 @@ function testProxy(url: string) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function testFebboxToken(
|
export async function testFebboxKey(febboxKey: string | null): Promise<Status> {
|
||||||
febboxToken: string | null,
|
|
||||||
): Promise<Status> {
|
|
||||||
const BASE_URL = await getBaseUrl();
|
const BASE_URL = await getBaseUrl();
|
||||||
const febboxApiTestUrl = `${BASE_URL}/movie/tt13654226`;
|
const febboxApiTestUrl = `${BASE_URL}/movie/tt13654226`;
|
||||||
|
|
||||||
if (!febboxToken) {
|
if (!febboxKey) {
|
||||||
return "unset";
|
return "unset";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +106,7 @@ export async function testFebboxToken(
|
||||||
try {
|
try {
|
||||||
const response = await fetch(febboxApiTestUrl, {
|
const response = await fetch(febboxApiTestUrl, {
|
||||||
headers: {
|
headers: {
|
||||||
"ui-token": febboxToken,
|
"ui-token": febboxKey,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -177,7 +176,7 @@ export async function testFebboxToken(
|
||||||
|
|
||||||
function useIsSetup() {
|
function useIsSetup() {
|
||||||
const proxyUrls = useAuthStore((s) => s.proxySet);
|
const proxyUrls = useAuthStore((s) => s.proxySet);
|
||||||
const febboxToken = useAuthStore((s) => s.febboxToken);
|
const febboxKey = usePreferencesStore((s) => s.febboxKey);
|
||||||
const { loading, value } = useAsync(async (): Promise<SetupData> => {
|
const { loading, value } = useAsync(async (): Promise<SetupData> => {
|
||||||
const extensionStatus: Status = (await isExtensionActive())
|
const extensionStatus: Status = (await isExtensionActive())
|
||||||
? "success"
|
? "success"
|
||||||
|
|
@ -192,29 +191,29 @@ function useIsSetup() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const febboxTokenStatus: Status = await testFebboxToken(febboxToken);
|
const febboxKeyStatus: Status = await testFebboxKey(febboxKey);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
extension: extensionStatus,
|
extension: extensionStatus,
|
||||||
proxy: proxyStatus,
|
proxy: proxyStatus,
|
||||||
defaultProxy: "success",
|
defaultProxy: "success",
|
||||||
...(conf().ALLOW_FEBBOX_KEY && {
|
...(conf().ALLOW_FEBBOX_KEY && {
|
||||||
febboxTokenTest: febboxTokenStatus,
|
febboxKeyTest: febboxKeyStatus,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}, [proxyUrls, febboxToken]);
|
}, [proxyUrls, febboxKey]);
|
||||||
|
|
||||||
let globalState: Status = "unset";
|
let globalState: Status = "unset";
|
||||||
if (
|
if (
|
||||||
value?.extension === "success" ||
|
value?.extension === "success" ||
|
||||||
value?.proxy === "success" ||
|
value?.proxy === "success" ||
|
||||||
value?.febboxTokenTest === "success"
|
value?.febboxKeyTest === "success"
|
||||||
)
|
)
|
||||||
globalState = "success";
|
globalState = "success";
|
||||||
if (
|
if (
|
||||||
value?.proxy === "error" ||
|
value?.proxy === "error" ||
|
||||||
value?.extension === "error" ||
|
value?.extension === "error" ||
|
||||||
value?.febboxTokenTest === "error"
|
value?.febboxKeyTest === "error"
|
||||||
)
|
)
|
||||||
globalState = "error";
|
globalState = "error";
|
||||||
|
|
||||||
|
|
@ -356,7 +355,7 @@ export function SetupPart() {
|
||||||
{t("settings.connections.setup.items.default")}
|
{t("settings.connections.setup.items.default")}
|
||||||
</SetupCheckList>
|
</SetupCheckList>
|
||||||
{conf().ALLOW_FEBBOX_KEY && (
|
{conf().ALLOW_FEBBOX_KEY && (
|
||||||
<SetupCheckList status={setupStates.febboxTokenTest || "unset"}>
|
<SetupCheckList status={setupStates.febboxKeyTest || "unset"}>
|
||||||
Febbox UI token
|
Febbox UI token
|
||||||
</SetupCheckList>
|
</SetupCheckList>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ interface AuthStore {
|
||||||
account: null | AccountWithToken;
|
account: null | AccountWithToken;
|
||||||
backendUrl: null | string;
|
backendUrl: null | string;
|
||||||
proxySet: null | string[];
|
proxySet: null | string[];
|
||||||
febboxToken: null | string;
|
|
||||||
removeAccount(): void;
|
removeAccount(): void;
|
||||||
setAccount(acc: AccountWithToken): void;
|
setAccount(acc: AccountWithToken): void;
|
||||||
updateDeviceName(deviceName: string): void;
|
updateDeviceName(deviceName: string): void;
|
||||||
|
|
@ -30,7 +29,6 @@ interface AuthStore {
|
||||||
setAccountProfile(acc: Account["profile"]): void;
|
setAccountProfile(acc: Account["profile"]): void;
|
||||||
setBackendUrl(url: null | string): void;
|
setBackendUrl(url: null | string): void;
|
||||||
setProxySet(urls: null | string[]): void;
|
setProxySet(urls: null | string[]): void;
|
||||||
setFebboxToken(token: null | string): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAuthStore = create(
|
export const useAuthStore = create(
|
||||||
|
|
@ -39,7 +37,6 @@ export const useAuthStore = create(
|
||||||
account: null,
|
account: null,
|
||||||
backendUrl: null,
|
backendUrl: null,
|
||||||
proxySet: null,
|
proxySet: null,
|
||||||
febboxToken: null,
|
|
||||||
setAccount(acc) {
|
setAccount(acc) {
|
||||||
set((s) => {
|
set((s) => {
|
||||||
s.account = acc;
|
s.account = acc;
|
||||||
|
|
@ -60,11 +57,6 @@ export const useAuthStore = create(
|
||||||
s.proxySet = urls;
|
s.proxySet = urls;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setFebboxToken(token) {
|
|
||||||
set((s) => {
|
|
||||||
s.febboxToken = token;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setAccountProfile(profile) {
|
setAccountProfile(profile) {
|
||||||
set((s) => {
|
set((s) => {
|
||||||
if (s.account) {
|
if (s.account) {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ export interface PreferencesStore {
|
||||||
sourceOrder: string[];
|
sourceOrder: string[];
|
||||||
enableSourceOrder: boolean;
|
enableSourceOrder: boolean;
|
||||||
proxyTmdb: boolean;
|
proxyTmdb: boolean;
|
||||||
|
febboxKey: string | null;
|
||||||
|
|
||||||
setEnableThumbnails(v: boolean): void;
|
setEnableThumbnails(v: boolean): void;
|
||||||
setEnableAutoplay(v: boolean): void;
|
setEnableAutoplay(v: boolean): void;
|
||||||
|
|
@ -26,6 +27,7 @@ export interface PreferencesStore {
|
||||||
setSourceOrder(v: string[]): void;
|
setSourceOrder(v: string[]): void;
|
||||||
setEnableSourceOrder(v: boolean): void;
|
setEnableSourceOrder(v: boolean): void;
|
||||||
setProxyTmdb(v: boolean): void;
|
setProxyTmdb(v: boolean): void;
|
||||||
|
setFebboxKey(v: string | null): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const usePreferencesStore = create(
|
export const usePreferencesStore = create(
|
||||||
|
|
@ -42,6 +44,7 @@ export const usePreferencesStore = create(
|
||||||
sourceOrder: [],
|
sourceOrder: [],
|
||||||
enableSourceOrder: false,
|
enableSourceOrder: false,
|
||||||
proxyTmdb: false,
|
proxyTmdb: false,
|
||||||
|
febboxKey: null,
|
||||||
setEnableThumbnails(v) {
|
setEnableThumbnails(v) {
|
||||||
set((s) => {
|
set((s) => {
|
||||||
s.enableThumbnails = v;
|
s.enableThumbnails = v;
|
||||||
|
|
@ -97,6 +100,11 @@ export const usePreferencesStore = create(
|
||||||
s.proxyTmdb = v;
|
s.proxyTmdb = v;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
setFebboxKey(v) {
|
||||||
|
set((s) => {
|
||||||
|
s.febboxKey = v;
|
||||||
|
});
|
||||||
|
},
|
||||||
})),
|
})),
|
||||||
{
|
{
|
||||||
name: "__MW::preferences",
|
name: "__MW::preferences",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue