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.",
"autoplayLabel": "Autoplay",
"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"
},
"reset": "Reset",

View File

@ -25,3 +25,11 @@ export function getProviders() {
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 {
id: string;
name: string;
disabled?: boolean;
}
function SortableItem(props: { item: Item }) {
@ -40,11 +41,13 @@ function SortableItem(props: { item: Item }) {
{...attributes}
{...listeners}
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",
transform && "cursor-grabbing",
"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",
props.item.disabled && "opacity-50",
transform ? "cursor-grabbing" : "cursor-grab",
)}
>
<span className="flex-1 text-white font-bold">{props.item.name}</span>
{props.item.disabled && <Icon icon={Icons.WARNING} />}
<Icon icon={Icons.MENU} />
</div>
);

View File

@ -11,7 +11,7 @@ import {
import { getSessions, updateSession } from "@/backend/accounts/sessions";
import { updateSettings } from "@/backend/accounts/settings";
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 { WideContainer } from "@/components/layout/WideContainer";
import { UserIcons } from "@/components/UserIcon";
@ -155,6 +155,22 @@ export function SettingsPage() {
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(() => {
setPreviewTheme(activeTheme ?? "default");
}, [setPreviewTheme, activeTheme]);
@ -281,13 +297,7 @@ export function SettingsPage() {
setEnableThumbnails={state.enableThumbnails.set}
enableAutoplay={state.enableAutoplay.state}
setEnableAutoplay={state.enableAutoplay.set}
sourceOrder={
state.sourceOrder.state.length > 0
? state.sourceOrder.state
: getProviders()
.listSources()
.map((s) => s.id)
}
sourceOrder={availableSources}
setSourceOrder={state.sourceOrder.set}
/>
</div>

View File

@ -1,7 +1,9 @@
import classNames from "classnames";
import { useMemo } from "react";
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 { FlagIcon } from "@/components/FlagIcon";
import { Dropdown } from "@/components/form/Dropdown";
@ -38,6 +40,17 @@ export function PreferencesPart(props: {
(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 (
<div className="space-y-12">
<Heading1 border>{t("settings.preferences.title")}</Heading1>
@ -108,17 +121,18 @@ export function PreferencesPart(props: {
</p>
<SortableList
items={props.sourceOrder.map((id) => ({
id,
name:
getProviders()
.listSources()
.find((s) => s.id === id)?.name || id,
}))}
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>
);