mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
grey out sources that are not available on your current device
This commit is contained in:
parent
d607a7cce1
commit
b671f22863
5 changed files with 54 additions and 19 deletions
|
@ -528,7 +528,7 @@
|
||||||
"autoplayDescription": "Automatically play the next episode in a series after reaching the end. Can be enabled by users with the browser extension, a custom proxy, or with the default setup if allowed by the host.",
|
"autoplayDescription": "Automatically play the next episode in a series after reaching the end. Can be enabled by users with the browser extension, a custom proxy, or with the default setup if allowed by the host.",
|
||||||
"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.",
|
"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"
|
||||||
},
|
},
|
||||||
"reset": "Reset",
|
"reset": "Reset",
|
||||||
|
|
|
@ -25,3 +25,11 @@ export function getProviders() {
|
||||||
target: targets.BROWSER,
|
target: targets.BROWSER,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAllProviders() {
|
||||||
|
return makeProviders({
|
||||||
|
fetcher: makeStandardFetcher(fetch),
|
||||||
|
target: targets.BROWSER_EXTENSION,
|
||||||
|
consistentIpForRequests: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { Icon, Icons } from "../Icon";
|
||||||
export interface Item {
|
export interface Item {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SortableItem(props: { item: Item }) {
|
function SortableItem(props: { item: Item }) {
|
||||||
|
@ -40,11 +41,13 @@ function SortableItem(props: { item: Item }) {
|
||||||
{...attributes}
|
{...attributes}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"bg-dropdown-background hover:bg-dropdown-hoverBackground select-none cursor-pointer space-x-3 flex items-center max-w-[25rem] py-3 px-4 rounded-lg touch-none",
|
"bg-dropdown-background hover:bg-dropdown-hoverBackground select-none space-x-3 flex items-center max-w-[25rem] py-3 px-4 rounded-lg touch-none",
|
||||||
transform && "cursor-grabbing",
|
props.item.disabled && "opacity-50",
|
||||||
|
transform ? "cursor-grabbing" : "cursor-grab",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span className="flex-1 text-white font-bold">{props.item.name}</span>
|
<span className="flex-1 text-white font-bold">{props.item.name}</span>
|
||||||
|
{props.item.disabled && <Icon icon={Icons.WARNING} />}
|
||||||
<Icon icon={Icons.MENU} />
|
<Icon icon={Icons.MENU} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
import { getSessions, updateSession } from "@/backend/accounts/sessions";
|
import { getSessions, updateSession } from "@/backend/accounts/sessions";
|
||||||
import { updateSettings } from "@/backend/accounts/settings";
|
import { updateSettings } from "@/backend/accounts/settings";
|
||||||
import { editUser } from "@/backend/accounts/user";
|
import { editUser } from "@/backend/accounts/user";
|
||||||
import { getProviders } from "@/backend/providers/providers";
|
import { getAllProviders, getProviders } from "@/backend/providers/providers";
|
||||||
import { Button } from "@/components/buttons/Button";
|
import { Button } from "@/components/buttons/Button";
|
||||||
import { WideContainer } from "@/components/layout/WideContainer";
|
import { WideContainer } from "@/components/layout/WideContainer";
|
||||||
import { UserIcons } from "@/components/UserIcon";
|
import { UserIcons } from "@/components/UserIcon";
|
||||||
|
@ -155,6 +155,22 @@ export function SettingsPage() {
|
||||||
sourceOrder,
|
sourceOrder,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const availableSources = useMemo(() => {
|
||||||
|
const sources = getAllProviders().listSources();
|
||||||
|
const sourceIDs = sources.map((s) => s.id);
|
||||||
|
const stateSources = state.sourceOrder.state;
|
||||||
|
|
||||||
|
// Filter out sources that are not in `stateSources` and are in `sources`
|
||||||
|
const updatedSources = stateSources.filter((ss) => sourceIDs.includes(ss));
|
||||||
|
|
||||||
|
// Add sources from `sources` that are not in `stateSources`
|
||||||
|
const missingSources = sources
|
||||||
|
.filter((s) => !stateSources.includes(s.id))
|
||||||
|
.map((s) => s.id);
|
||||||
|
|
||||||
|
return [...updatedSources, ...missingSources];
|
||||||
|
}, [state.sourceOrder.state]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPreviewTheme(activeTheme ?? "default");
|
setPreviewTheme(activeTheme ?? "default");
|
||||||
}, [setPreviewTheme, activeTheme]);
|
}, [setPreviewTheme, activeTheme]);
|
||||||
|
@ -281,13 +297,7 @@ export function SettingsPage() {
|
||||||
setEnableThumbnails={state.enableThumbnails.set}
|
setEnableThumbnails={state.enableThumbnails.set}
|
||||||
enableAutoplay={state.enableAutoplay.state}
|
enableAutoplay={state.enableAutoplay.state}
|
||||||
setEnableAutoplay={state.enableAutoplay.set}
|
setEnableAutoplay={state.enableAutoplay.set}
|
||||||
sourceOrder={
|
sourceOrder={availableSources}
|
||||||
state.sourceOrder.state.length > 0
|
|
||||||
? state.sourceOrder.state
|
|
||||||
: getProviders()
|
|
||||||
.listSources()
|
|
||||||
.map((s) => s.id)
|
|
||||||
}
|
|
||||||
setSourceOrder={state.sourceOrder.set}
|
setSourceOrder={state.sourceOrder.set}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
import { useMemo } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { getProviders } from "@/backend/providers/providers";
|
import { getAllProviders, getProviders } from "@/backend/providers/providers";
|
||||||
|
import { Button } from "@/components/buttons/Button";
|
||||||
import { Toggle } from "@/components/buttons/Toggle";
|
import { Toggle } from "@/components/buttons/Toggle";
|
||||||
import { FlagIcon } from "@/components/FlagIcon";
|
import { FlagIcon } from "@/components/FlagIcon";
|
||||||
import { Dropdown } from "@/components/form/Dropdown";
|
import { Dropdown } from "@/components/form/Dropdown";
|
||||||
|
@ -38,6 +40,17 @@ export function PreferencesPart(props: {
|
||||||
(item) => item.id === getLocaleInfo(props.language)?.code,
|
(item) => item.id === getLocaleInfo(props.language)?.code,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const allSources = getAllProviders().listSources();
|
||||||
|
|
||||||
|
const sourceItems = useMemo(() => {
|
||||||
|
const currentDeviceSources = getProviders().listSources();
|
||||||
|
return props.sourceOrder.map((id) => ({
|
||||||
|
id,
|
||||||
|
name: allSources.find((s) => s.id === id)?.name || id,
|
||||||
|
disabled: !currentDeviceSources.find((s) => s.id === id),
|
||||||
|
}));
|
||||||
|
}, [props.sourceOrder, allSources]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-12">
|
<div className="space-y-12">
|
||||||
<Heading1 border>{t("settings.preferences.title")}</Heading1>
|
<Heading1 border>{t("settings.preferences.title")}</Heading1>
|
||||||
|
@ -108,17 +121,18 @@ export function PreferencesPart(props: {
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<SortableList
|
<SortableList
|
||||||
items={props.sourceOrder.map((id) => ({
|
items={sourceItems}
|
||||||
id,
|
|
||||||
name:
|
|
||||||
getProviders()
|
|
||||||
.listSources()
|
|
||||||
.find((s) => s.id === id)?.name || id,
|
|
||||||
}))}
|
|
||||||
setItems={(items) =>
|
setItems={(items) =>
|
||||||
props.setSourceOrder(items.map((item) => item.id))
|
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>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue