1
0
Fork 0
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:
Jorrin 2024-04-15 22:46:38 +02:00
parent d607a7cce1
commit b671f22863
5 changed files with 54 additions and 19 deletions

View file

@ -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",

View file

@ -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,
});
}

View file

@ -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>
); );

View file

@ -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>

View file

@ -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>
); );