Merge branch 'dev' into extension

This commit is contained in:
mrjvs 2024-01-20 14:57:40 +01:00 committed by GitHub
commit 8a79924abd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 48 additions and 25 deletions

View File

@ -173,7 +173,7 @@ jobs:
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
push: true push: true
platforms: linux/amd64,linux/arm64,linux/arm platforms: linux/amd64,linux/arm64
context: . context: .
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}

View File

@ -416,14 +416,14 @@
} }
}, },
"server": { "server": {
"description": "If you would like to connect to a custom backend to store your data, enable this and provide the URL.", "description": "If you would like to connect to a custom backend to store your data, enable this and provide the URL. <0>Instructions.</0>",
"label": "Custom server", "label": "Custom server",
"urlLabel": "Custom server URL" "urlLabel": "Custom server URL"
}, },
"title": "Connections", "title": "Connections",
"workers": { "workers": {
"addButton": "Add new worker", "addButton": "Add new worker",
"description": "To make the application function, all traffic is routed through proxies. Enable this if you want to bring your own workers.", "description": "To make the application function, all traffic is routed through proxies. Enable this if you want to bring your own workers. <0>Instructions.</0>",
"emptyState": "No workers yet, add one below", "emptyState": "No workers yet, add one below",
"label": "Use custom proxy workers", "label": "Use custom proxy workers",
"urlLabel": "Worker URLs", "urlLabel": "Worker URLs",

View File

@ -41,7 +41,7 @@ export function Button(props: Props) {
props.padding ?? "px-4 py-3", props.padding ?? "px-4 py-3",
props.className, props.className,
colorClasses, colorClasses,
props.disabled ? "cursor-not-allowed bg-opacity-60 text-opacity-60" : null, props.disabled ? "!cursor-not-allowed bg-opacity-60 text-opacity-60" : null,
); );
if (props.disabled) if (props.disabled)

View File

@ -75,6 +75,7 @@ function CustomCaptionOption() {
setCaption({ setCaption({
language: "custom", language: "custom",
srtData: converted, srtData: converted,
id: "custom-caption",
}); });
setCustomSubs(); setCustomSubs();
}); });
@ -115,39 +116,38 @@ function useSubtitleList(subs: CaptionListItem[], searchQuery: string) {
export function CaptionsView({ id }: { id: string }) { export function CaptionsView({ id }: { id: string }) {
const { t } = useTranslation(); const { t } = useTranslation();
const router = useOverlayRouter(id); const router = useOverlayRouter(id);
const lang = usePlayerStore((s) => s.caption.selected?.language); const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id);
const [currentlyDownloading, setCurrentlyDownloading] = useState< const [currentlyDownloading, setCurrentlyDownloading] = useState<
string | null string | null
>(null); >(null);
const { selectLanguage, disable } = useCaptions(); const { selectCaptionById, disable } = useCaptions();
const captionList = usePlayerStore((s) => s.captionList); const captionList = usePlayerStore((s) => s.captionList);
const [searchQuery, setSearchQuery] = useState(""); const [searchQuery, setSearchQuery] = useState("");
const subtitleList = useSubtitleList(captionList, searchQuery); const subtitleList = useSubtitleList(captionList, searchQuery);
const [downloadReq, startDownload] = useAsyncFn( const [downloadReq, startDownload] = useAsyncFn(
async (language: string) => { async (captionId: string) => {
setCurrentlyDownloading(language); setCurrentlyDownloading(captionId);
return selectLanguage(language); return selectCaptionById(captionId);
}, },
[selectLanguage, setCurrentlyDownloading], [selectCaptionById, setCurrentlyDownloading],
); );
const content = subtitleList.map((v, i) => { const content = subtitleList.map((v, i) => {
return ( return (
<CaptionOption <CaptionOption
// key must use index to prevent url collisions // key must use index to prevent url collisions
// eslint-disable-next-line react/no-array-index-key key={v.id}
key={`${i}-${v.url}`}
countryCode={v.language} countryCode={v.language}
selected={lang === v.language} selected={v.id === selectedCaptionId}
loading={v.language === currentlyDownloading && downloadReq.loading} loading={v.id === currentlyDownloading && downloadReq.loading}
error={ error={
v.language === currentlyDownloading && downloadReq.error v.id === currentlyDownloading && downloadReq.error
? downloadReq.error.toString() ? downloadReq.error.toString()
: undefined : undefined
} }
onClick={() => startDownload(v.language)} onClick={() => startDownload(v.id)}
> >
{v.languageName} {v.languageName}
</CaptionOption> </CaptionOption>
@ -176,7 +176,7 @@ export function CaptionsView({ id }: { id: string }) {
</div> </div>
</div> </div>
<Menu.ScrollToActiveSection className="!pt-1 mt-2 pb-3"> <Menu.ScrollToActiveSection className="!pt-1 mt-2 pb-3">
<CaptionOption onClick={() => disable()} selected={!lang}> <CaptionOption onClick={() => disable()} selected={!selectedCaptionId}>
{t("player.menus.subtitles.offChoice")} {t("player.menus.subtitles.offChoice")}
</CaptionOption> </CaptionOption>
<CustomCaptionOption /> <CustomCaptionOption />

View File

@ -41,6 +41,7 @@ export interface DisplayMeta {
} }
export interface DisplayCaption { export interface DisplayCaption {
id: string;
srtData: string; srtData: string;
language: string; language: string;
url?: string; url?: string;

View File

@ -14,22 +14,32 @@ export function useCaptions() {
const lastSelectedLanguage = useSubtitleStore((s) => s.lastSelectedLanguage); const lastSelectedLanguage = useSubtitleStore((s) => s.lastSelectedLanguage);
const captionList = usePlayerStore((s) => s.captionList); const captionList = usePlayerStore((s) => s.captionList);
const selectLanguage = useCallback( const selectCaptionById = useCallback(
async (language: string) => { async (captionId: string) => {
const caption = captionList.find((v) => v.language === language); const caption = captionList.find((v) => v.id === captionId);
if (!caption) return; if (!caption) return;
const srtData = await downloadCaption(caption); const srtData = await downloadCaption(caption);
setCaption({ setCaption({
id: caption.id,
language: caption.language, language: caption.language,
srtData, srtData,
url: caption.url, url: caption.url,
}); });
resetSubtitleSpecificSettings(); resetSubtitleSpecificSettings();
setLanguage(language); setLanguage(caption.language);
}, },
[setLanguage, captionList, setCaption, resetSubtitleSpecificSettings], [setLanguage, captionList, setCaption, resetSubtitleSpecificSettings],
); );
const selectLanguage = useCallback(
async (language: string) => {
const caption = captionList.find((v) => v.language === language);
if (!caption) return;
return selectCaptionById(caption.id);
},
[captionList, selectCaptionById],
);
const disable = useCallback(async () => { const disable = useCallback(async () => {
setCaption(null); setCaption(null);
setLanguage(null); setLanguage(null);
@ -56,5 +66,6 @@ export function useCaptions() {
selectLastUsedLanguage, selectLastUsedLanguage,
toggleLastUsed, toggleLastUsed,
selectLastUsedLanguageIfEnabled, selectLastUsedLanguageIfEnabled,
selectCaptionById,
}; };
} }

View File

@ -80,6 +80,7 @@ export function convertProviderCaption(
captions: RunOutput["stream"]["captions"], captions: RunOutput["stream"]["captions"],
): CaptionListItem[] { ): CaptionListItem[] {
return captions.map((v) => ({ return captions.map((v) => ({
id: v.id,
language: v.language, language: v.language,
url: v.url, url: v.url,
needsProxy: v.hasCorsRestrictions, needsProxy: v.hasCorsRestrictions,

View File

@ -5,7 +5,6 @@ import { Avatar } from "@/components/Avatar";
import { Button } from "@/components/buttons/Button"; import { Button } from "@/components/buttons/Button";
import { ColorPicker, initialColor } from "@/components/form/ColorPicker"; import { ColorPicker, initialColor } from "@/components/form/ColorPicker";
import { IconPicker, initialIcon } from "@/components/form/IconPicker"; import { IconPicker, initialIcon } from "@/components/form/IconPicker";
import { Icon, Icons } from "@/components/Icon";
import { import {
LargeCard, LargeCard,
LargeCardButtons, LargeCardButtons,

View File

@ -1,10 +1,11 @@
import { Dispatch, SetStateAction, useCallback } from "react"; import { Dispatch, SetStateAction, useCallback } from "react";
import { useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import { Button } from "@/components/buttons/Button"; import { Button } from "@/components/buttons/Button";
import { Toggle } from "@/components/buttons/Toggle"; import { Toggle } from "@/components/buttons/Toggle";
import { Icon, Icons } from "@/components/Icon"; import { Icon, Icons } from "@/components/Icon";
import { SettingsCard } from "@/components/layout/SettingsCard"; import { SettingsCard } from "@/components/layout/SettingsCard";
import { MwLink } from "@/components/text/Link";
import { AuthInputBox } from "@/components/text-inputs/AuthInputBox"; import { AuthInputBox } from "@/components/text-inputs/AuthInputBox";
import { Divider } from "@/components/utils/Divider"; import { Divider } from "@/components/utils/Divider";
import { Heading1 } from "@/components/utils/Text"; import { Heading1 } from "@/components/utils/Text";
@ -53,7 +54,11 @@ function ProxyEdit({ proxyUrls, setProxyUrls }: ProxyEditProps) {
{t("settings.connections.workers.label")} {t("settings.connections.workers.label")}
</p> </p>
<p className="max-w-[20rem] font-medium"> <p className="max-w-[20rem] font-medium">
{t("settings.connections.workers.description")} <Trans i18nKey="settings.connections.workers.description">
<MwLink to="https://docs.movie-web.app/proxy/deploy">
Proxy documentation
</MwLink>
</Trans>
</p> </p>
</div> </div>
<div> <div>
@ -119,7 +124,11 @@ function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) {
{t("settings.connections.server.label")} {t("settings.connections.server.label")}
</p> </p>
<p className="max-w-[20rem] font-medium"> <p className="max-w-[20rem] font-medium">
{t("settings.connections.server.description")} <Trans i18nKey="settings.connections.server.description">
<MwLink to="https://docs.movie-web.app/backend/deploy">
Backend documentation
</MwLink>
</Trans>
</p> </p>
</div> </div>
<div> <div>

View File

@ -42,12 +42,14 @@ export interface PlayerMeta {
} }
export interface Caption { export interface Caption {
id: string;
language: string; language: string;
url?: string; url?: string;
srtData: string; srtData: string;
} }
export interface CaptionListItem { export interface CaptionListItem {
id: string;
language: string; language: string;
url: string; url: string;
needsProxy: boolean; needsProxy: boolean;