mirror of
https://github.com/p-stream/p-stream.git
synced 2026-05-12 10:41:12 +00:00
Add toggle for custom source order
This commit is contained in:
parent
2e6c172071
commit
533773873c
6 changed files with 81 additions and 20 deletions
|
|
@ -618,7 +618,8 @@
|
||||||
"autoplayLabel": "Autoplay",
|
"autoplayLabel": "Autoplay",
|
||||||
"sourceOrder": "Reordering sources",
|
"sourceOrder": "Reordering sources",
|
||||||
"sourceOrderDescription": "Drag and drop to reorder sources. This will determine the order in which sources are checked for the media you are trying to watch. If a source is greyed out, it means it is not available on your device.",
|
"sourceOrderDescription": "Drag and drop to reorder sources. This will determine the order in which sources are checked for the media you are trying to watch. If a source is greyed out, it means it is not available on your device.",
|
||||||
"title": "Preferences"
|
"title": "Preferences",
|
||||||
|
"sourceOrderEnableLabel": "Custom source order"
|
||||||
},
|
},
|
||||||
"reset": "Reset",
|
"reset": "Reset",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ export function useScrape() {
|
||||||
} = useBaseScrape();
|
} = useBaseScrape();
|
||||||
|
|
||||||
const preferredSourceOrder = usePreferencesStore((s) => s.sourceOrder);
|
const preferredSourceOrder = usePreferencesStore((s) => s.sourceOrder);
|
||||||
|
const enableSourceOrder = usePreferencesStore((s) => s.enableSourceOrder);
|
||||||
|
|
||||||
const startScraping = useCallback(
|
const startScraping = useCallback(
|
||||||
async (media: ScrapeMedia) => {
|
async (media: ScrapeMedia) => {
|
||||||
|
|
@ -184,7 +185,8 @@ export function useScrape() {
|
||||||
const providers = getProviders();
|
const providers = getProviders();
|
||||||
const output = await providers.runAll({
|
const output = await providers.runAll({
|
||||||
media,
|
media,
|
||||||
sourceOrder: preferredSourceOrder,
|
// Only pass sourceOrder if enableSourceOrder is true
|
||||||
|
sourceOrder: enableSourceOrder ? preferredSourceOrder : undefined,
|
||||||
events: {
|
events: {
|
||||||
init: initEvent,
|
init: initEvent,
|
||||||
start: startEvent,
|
start: startEvent,
|
||||||
|
|
@ -204,6 +206,7 @@ export function useScrape() {
|
||||||
getResult,
|
getResult,
|
||||||
startScrape,
|
startScrape,
|
||||||
preferredSourceOrder,
|
preferredSourceOrder,
|
||||||
|
enableSourceOrder,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ export function useSettingsState(
|
||||||
enableThumbnails: boolean,
|
enableThumbnails: boolean,
|
||||||
enableAutoplay: boolean,
|
enableAutoplay: boolean,
|
||||||
sourceOrder: string[],
|
sourceOrder: string[],
|
||||||
|
enableSourceOrder: boolean,
|
||||||
) {
|
) {
|
||||||
const [proxyUrlsState, setProxyUrls, resetProxyUrls, proxyUrlsChanged] =
|
const [proxyUrlsState, setProxyUrls, resetProxyUrls, proxyUrlsChanged] =
|
||||||
useDerived(proxyUrls);
|
useDerived(proxyUrls);
|
||||||
|
|
@ -98,6 +99,12 @@ export function useSettingsState(
|
||||||
resetSourceOrder,
|
resetSourceOrder,
|
||||||
sourceOrderChanged,
|
sourceOrderChanged,
|
||||||
] = useDerived(sourceOrder);
|
] = useDerived(sourceOrder);
|
||||||
|
const [
|
||||||
|
enableSourceOrderState,
|
||||||
|
setEnableSourceOrderState,
|
||||||
|
resetEnableSourceOrder,
|
||||||
|
enableSourceOrderChanged,
|
||||||
|
] = useDerived(enableSourceOrder);
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
resetTheme();
|
resetTheme();
|
||||||
|
|
@ -111,6 +118,7 @@ export function useSettingsState(
|
||||||
resetEnableThumbnails();
|
resetEnableThumbnails();
|
||||||
resetEnableAutoplay();
|
resetEnableAutoplay();
|
||||||
resetSourceOrder();
|
resetSourceOrder();
|
||||||
|
resetEnableSourceOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
const changed =
|
const changed =
|
||||||
|
|
@ -123,7 +131,8 @@ export function useSettingsState(
|
||||||
profileChanged ||
|
profileChanged ||
|
||||||
enableThumbnailsChanged ||
|
enableThumbnailsChanged ||
|
||||||
enableAutoplayChanged ||
|
enableAutoplayChanged ||
|
||||||
sourceOrderChanged;
|
sourceOrderChanged ||
|
||||||
|
enableSourceOrderChanged;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reset,
|
reset,
|
||||||
|
|
@ -178,5 +187,10 @@ export function useSettingsState(
|
||||||
set: setSourceOrderState,
|
set: setSourceOrderState,
|
||||||
changed: sourceOrderChanged,
|
changed: sourceOrderChanged,
|
||||||
},
|
},
|
||||||
|
enableSourceOrder: {
|
||||||
|
state: enableSourceOrderState,
|
||||||
|
set: setEnableSourceOrderState,
|
||||||
|
changed: enableSourceOrderChanged,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,16 @@ export function AccountSettings(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SettingsPage() {
|
export function SettingsPage() {
|
||||||
|
useEffect(() => {
|
||||||
|
const hash = window.location.hash;
|
||||||
|
if (hash) {
|
||||||
|
const element = document.querySelector(hash);
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const activeTheme = useThemeStore((s) => s.theme);
|
const activeTheme = useThemeStore((s) => s.theme);
|
||||||
const setTheme = useThemeStore((s) => s.setTheme);
|
const setTheme = useThemeStore((s) => s.setTheme);
|
||||||
|
|
@ -130,6 +140,11 @@ export function SettingsPage() {
|
||||||
const sourceOrder = usePreferencesStore((s) => s.sourceOrder);
|
const sourceOrder = usePreferencesStore((s) => s.sourceOrder);
|
||||||
const setSourceOrder = usePreferencesStore((s) => s.setSourceOrder);
|
const setSourceOrder = usePreferencesStore((s) => s.setSourceOrder);
|
||||||
|
|
||||||
|
const enableSourceOrder = usePreferencesStore((s) => s.enableSourceOrder);
|
||||||
|
const setEnableSourceOrder = usePreferencesStore(
|
||||||
|
(s) => s.setEnableSourceOrder,
|
||||||
|
);
|
||||||
|
|
||||||
const account = useAuthStore((s) => s.account);
|
const account = useAuthStore((s) => s.account);
|
||||||
const updateProfile = useAuthStore((s) => s.setAccountProfile);
|
const updateProfile = useAuthStore((s) => s.setAccountProfile);
|
||||||
const updateDeviceName = useAuthStore((s) => s.updateDeviceName);
|
const updateDeviceName = useAuthStore((s) => s.updateDeviceName);
|
||||||
|
|
@ -154,6 +169,7 @@ export function SettingsPage() {
|
||||||
enableThumbnails,
|
enableThumbnails,
|
||||||
enableAutoplay,
|
enableAutoplay,
|
||||||
sourceOrder,
|
sourceOrder,
|
||||||
|
enableSourceOrder,
|
||||||
);
|
);
|
||||||
|
|
||||||
const availableSources = useMemo(() => {
|
const availableSources = useMemo(() => {
|
||||||
|
|
@ -228,6 +244,7 @@ export function SettingsPage() {
|
||||||
setTheme(state.theme.state);
|
setTheme(state.theme.state);
|
||||||
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);
|
||||||
|
|
||||||
if (state.profile.state) {
|
if (state.profile.state) {
|
||||||
updateProfile(state.profile.state);
|
updateProfile(state.profile.state);
|
||||||
|
|
@ -259,6 +276,7 @@ export function SettingsPage() {
|
||||||
updateProfile,
|
updateProfile,
|
||||||
logout,
|
logout,
|
||||||
setBackendUrl,
|
setBackendUrl,
|
||||||
|
setEnableSourceOrder,
|
||||||
]);
|
]);
|
||||||
return (
|
return (
|
||||||
<SubPageLayout>
|
<SubPageLayout>
|
||||||
|
|
@ -293,7 +311,7 @@ export function SettingsPage() {
|
||||||
<div className="mt-10">
|
<div className="mt-10">
|
||||||
<AdminPanelPart />
|
<AdminPanelPart />
|
||||||
</div>
|
</div>
|
||||||
<div id="settings-preferences" className="mt-48">
|
<div id="settings-preferences" className="mt-28">
|
||||||
<PreferencesPart
|
<PreferencesPart
|
||||||
language={state.appLanguage.state}
|
language={state.appLanguage.state}
|
||||||
setLanguage={state.appLanguage.set}
|
setLanguage={state.appLanguage.set}
|
||||||
|
|
@ -303,22 +321,24 @@ export function SettingsPage() {
|
||||||
setEnableAutoplay={state.enableAutoplay.set}
|
setEnableAutoplay={state.enableAutoplay.set}
|
||||||
sourceOrder={availableSources}
|
sourceOrder={availableSources}
|
||||||
setSourceOrder={state.sourceOrder.set}
|
setSourceOrder={state.sourceOrder.set}
|
||||||
|
enableSourceOrder={state.enableSourceOrder.state}
|
||||||
|
setEnableSourceOrder={state.enableSourceOrder.set}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div id="settings-appearance" className="mt-48">
|
<div id="settings-appearance" className="mt-28">
|
||||||
<ThemePart
|
<ThemePart
|
||||||
active={previewTheme ?? "default"}
|
active={previewTheme ?? "default"}
|
||||||
inUse={activeTheme ?? "default"}
|
inUse={activeTheme ?? "default"}
|
||||||
setTheme={setThemeWithPreview}
|
setTheme={setThemeWithPreview}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div id="settings-captions" className="mt-48">
|
<div id="settings-captions" className="mt-28">
|
||||||
<CaptionsPart
|
<CaptionsPart
|
||||||
styling={state.subtitleStyling.state}
|
styling={state.subtitleStyling.state}
|
||||||
setStyling={state.subtitleStyling.set}
|
setStyling={state.subtitleStyling.set}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div id="settings-connection" className="mt-48">
|
<div id="settings-connection" className="mt-28">
|
||||||
<ConnectionsPart
|
<ConnectionsPart
|
||||||
backendUrl={state.backendUrl.state}
|
backendUrl={state.backendUrl.state}
|
||||||
setBackendUrl={state.backendUrl.set}
|
setBackendUrl={state.backendUrl.set}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ export function PreferencesPart(props: {
|
||||||
setEnableAutoplay: (v: boolean) => void;
|
setEnableAutoplay: (v: boolean) => void;
|
||||||
sourceOrder: string[];
|
sourceOrder: string[];
|
||||||
setSourceOrder: (v: string[]) => void;
|
setSourceOrder: (v: string[]) => void;
|
||||||
|
enableSourceOrder: boolean;
|
||||||
|
setEnableSourceOrder: (v: boolean) => void;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const sorted = sortLangCodes(appLanguageOptions.map((item) => item.code));
|
const sorted = sortLangCodes(appLanguageOptions.map((item) => item.code));
|
||||||
|
|
@ -119,20 +121,33 @@ export function PreferencesPart(props: {
|
||||||
<p className="max-w-[25rem] font-medium">
|
<p className="max-w-[25rem] font-medium">
|
||||||
{t("settings.preferences.sourceOrderDescription")}
|
{t("settings.preferences.sourceOrderDescription")}
|
||||||
</p>
|
</p>
|
||||||
|
<div
|
||||||
<SortableList
|
onClick={() => props.setEnableSourceOrder(!props.enableSourceOrder)}
|
||||||
items={sourceItems}
|
className="bg-dropdown-background hover:bg-dropdown-hoverBackground select-none my-4 cursor-pointer space-x-3 flex items-center max-w-[25rem] py-3 px-4 rounded-lg"
|
||||||
setItems={(items) =>
|
|
||||||
props.setSourceOrder(items.map((item) => item.id))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
className="max-w-[25rem]"
|
|
||||||
theme="secondary"
|
|
||||||
onClick={() => props.setSourceOrder(allSources.map((s) => s.id))}
|
|
||||||
>
|
>
|
||||||
{t("settings.reset")}
|
<Toggle enabled={props.enableSourceOrder} />
|
||||||
</Button>
|
<p className="flex-1 text-white font-bold">
|
||||||
|
{t("settings.preferences.sourceOrderEnableLabel")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{props.enableSourceOrder && (
|
||||||
|
<div className="w-full flex flex-col gap-4">
|
||||||
|
<SortableList
|
||||||
|
items={sourceItems}
|
||||||
|
setItems={(items) =>
|
||||||
|
props.setSourceOrder(items.map((item) => item.id))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="max-w-[25rem]"
|
||||||
|
theme="secondary"
|
||||||
|
onClick={() => props.setSourceOrder(allSources.map((s) => s.id))}
|
||||||
|
>
|
||||||
|
{t("settings.reset")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,12 @@ export interface PreferencesStore {
|
||||||
enableThumbnails: boolean;
|
enableThumbnails: boolean;
|
||||||
enableAutoplay: boolean;
|
enableAutoplay: boolean;
|
||||||
sourceOrder: string[];
|
sourceOrder: string[];
|
||||||
|
enableSourceOrder: boolean;
|
||||||
|
|
||||||
setEnableThumbnails(v: boolean): void;
|
setEnableThumbnails(v: boolean): void;
|
||||||
setEnableAutoplay(v: boolean): void;
|
setEnableAutoplay(v: boolean): void;
|
||||||
setSourceOrder(v: string[]): void;
|
setSourceOrder(v: string[]): void;
|
||||||
|
setEnableSourceOrder(v: boolean): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const usePreferencesStore = create(
|
export const usePreferencesStore = create(
|
||||||
|
|
@ -18,6 +20,7 @@ export const usePreferencesStore = create(
|
||||||
enableThumbnails: false,
|
enableThumbnails: false,
|
||||||
enableAutoplay: true,
|
enableAutoplay: true,
|
||||||
sourceOrder: [],
|
sourceOrder: [],
|
||||||
|
enableSourceOrder: false,
|
||||||
setEnableThumbnails(v) {
|
setEnableThumbnails(v) {
|
||||||
set((s) => {
|
set((s) => {
|
||||||
s.enableThumbnails = v;
|
s.enableThumbnails = v;
|
||||||
|
|
@ -33,6 +36,11 @@ export const usePreferencesStore = create(
|
||||||
s.sourceOrder = v;
|
s.sourceOrder = v;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
setEnableSourceOrder(v) {
|
||||||
|
set((s) => {
|
||||||
|
s.enableSourceOrder = v;
|
||||||
|
});
|
||||||
|
},
|
||||||
})),
|
})),
|
||||||
{
|
{
|
||||||
name: "__MW::preferences",
|
name: "__MW::preferences",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue