feat: add autoplay configurability with `VITE_ALLOW_AUTOPLAY` and custom proxy

This commit is contained in:
qtchaos 2024-04-01 00:43:00 +03:00
parent 20cec61eac
commit 34168a7037
No known key found for this signature in database
GPG Key ID: 7DA98B2B9EF06A90
6 changed files with 29 additions and 22 deletions

View File

@ -23,6 +23,7 @@ ARG ONBOARDING_PROXY_INSTALL_LINK
ARG DISALLOWED_IDS ARG DISALLOWED_IDS
ARG CDN_REPLACEMENTS ARG CDN_REPLACEMENTS
ARG TURNSTILE_KEY ARG TURNSTILE_KEY
ARG ALLOW_AUTOPLAY="false"
ENV VITE_PWA_ENABLED=${PWA_ENABLED} ENV VITE_PWA_ENABLED=${PWA_ENABLED}
ENV VITE_GA_ID=${GA_ID} ENV VITE_GA_ID=${GA_ID}
@ -39,6 +40,7 @@ ENV VITE_ONBOARDING_PROXY_INSTALL_LINK=${ONBOARDING_PROXY_INSTALL_LINK}
ENV VITE_DISALLOWED_IDS=${DISALLOWED_IDS} ENV VITE_DISALLOWED_IDS=${DISALLOWED_IDS}
ENV VITE_CDN_REPLACEMENTS=${CDN_REPLACEMENTS} ENV VITE_CDN_REPLACEMENTS=${CDN_REPLACEMENTS}
ENV VITE_TURNSTILE_KEY=${TURNSTILE_KEY} ENV VITE_TURNSTILE_KEY=${TURNSTILE_KEY}
ENV VITE_ALLOW_AUTOPLAY=${ALLOW_AUTOPLAY}
COPY . ./ COPY . ./
RUN pnpm run build RUN pnpm run build

View File

@ -524,7 +524,7 @@
"thumbnailDescription": "Most of the time, videos don't have thumbnails. You can enable this setting to generate them on the fly but they can make your video slower.", "thumbnailDescription": "Most of the time, videos don't have thumbnails. You can enable this setting to generate them on the fly but they can make your video slower.",
"thumbnailLabel": "Generate thumbnails", "thumbnailLabel": "Generate thumbnails",
"autoplay": "Autoplay", "autoplay": "Autoplay",
"autoplayDescription": "Automatically play the next episode in a series after reaching the end. This feature is reserved only for extension users.", "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",
"title": "Preferences" "title": "Preferences"
}, },

View File

@ -7,6 +7,8 @@ import { isExtensionActiveCached } from "@/backend/extension/messaging";
import { Icon, Icons } from "@/components/Icon"; import { Icon, Icons } from "@/components/Icon";
import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta"; import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta";
import { Transition } from "@/components/utils/Transition"; import { Transition } from "@/components/utils/Transition";
import { conf } from "@/setup/config";
import { useAuthStore } from "@/stores/auth";
import { PlayerMeta } from "@/stores/player/slices/source"; import { PlayerMeta } from "@/stores/player/slices/source";
import { usePlayerStore } from "@/stores/player/store"; import { usePlayerStore } from "@/stores/player/store";
import { usePreferencesStore } from "@/stores/preferences"; import { usePreferencesStore } from "@/stores/preferences";
@ -105,7 +107,13 @@ export function NextEpisodeButton(props: {
const isEnding = time >= duration - halfPercent && duration !== 0; const isEnding = time >= duration - halfPercent && duration !== 0;
const debouncedLoadNextEpisode = throttle(debounce(loadNextEpisode), 300); const debouncedLoadNextEpisode = throttle(debounce(loadNextEpisode), 300);
if (isEnding && isExtensionActiveCached()) debouncedLoadNextEpisode(); const allowAutoplay = Boolean(
conf().ALLOW_AUTOPLAY ||
isExtensionActiveCached() ||
useAuthStore.getState().proxySet,
);
if (isEnding && allowAutoplay) debouncedLoadNextEpisode();
return () => { return () => {
debouncedLoadNextEpisode.cancel(); debouncedLoadNextEpisode.cancel();

View File

@ -225,21 +225,7 @@ export function SettingsPage() {
account, account,
backendUrl, backendUrl,
setEnableThumbnails, setEnableThumbnails,
state.enableThumbnails.state, state,
state.enableAutoplay.state,
state.appLanguage.state,
state.appLanguage.changed,
state.theme.state,
state.theme.changed,
state.subtitleStyling.state,
state.proxyUrls.state,
state.proxyUrls.changed,
state.profile.state,
state.profile.changed,
state.backendUrl.changed,
state.backendUrl.state,
state.deviceName.changed,
state.deviceName.state,
setEnableAutoplay, setEnableAutoplay,
setAppLanguage, setAppLanguage,
setTheme, setTheme,

View File

@ -6,7 +6,9 @@ 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";
import { Heading1 } from "@/components/utils/Text"; import { Heading1 } from "@/components/utils/Text";
import { conf } from "@/setup/config";
import { appLanguageOptions } from "@/setup/i18n"; import { appLanguageOptions } from "@/setup/i18n";
import { useAuthStore } from "@/stores/auth";
import { getLocaleInfo, sortLangCodes } from "@/utils/language"; import { getLocaleInfo, sortLangCodes } from "@/utils/language";
function useIsExtensionActive() { function useIsExtensionActive() {
@ -34,6 +36,11 @@ export function PreferencesPart(props: {
const { loading, active } = useIsExtensionActive(); const { loading, active } = useIsExtensionActive();
const extensionActive = active && !loading; const extensionActive = active && !loading;
const allowAutoplay = Boolean(
conf().ALLOW_AUTOPLAY ||
extensionActive ||
useAuthStore.getState().proxySet,
);
const options = appLanguageOptions const options = appLanguageOptions
.sort((a, b) => sorted.indexOf(a.code) - sorted.indexOf(b.code)) .sort((a, b) => sorted.indexOf(a.code) - sorted.indexOf(b.code))
@ -90,18 +97,18 @@ export function PreferencesPart(props: {
</p> </p>
<div <div
onClick={() => onClick={() =>
extensionActive allowAutoplay
? props.setEnableAutoplay(!props.enableAutoplay) ? props.setEnableAutoplay(!props.enableAutoplay)
: null : null
} }
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" 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"
style={{ style={{
pointerEvents: extensionActive ? "auto" : "none", pointerEvents: allowAutoplay ? "auto" : "none",
opacity: extensionActive ? 1 : 0.5, opacity: allowAutoplay ? 1 : 0.5,
cursor: extensionActive ? "pointer" : "not-allowed", cursor: allowAutoplay ? "pointer" : "not-allowed",
}} }}
> >
<Toggle enabled={props.enableAutoplay && extensionActive} /> <Toggle enabled={props.enableAutoplay && allowAutoplay} />
<p className="flex-1 text-white font-bold"> <p className="flex-1 text-white font-bold">
{t("settings.preferences.autoplayLabel")} {t("settings.preferences.autoplayLabel")}
</p> </p>

View File

@ -23,6 +23,7 @@ interface Config {
ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: string; ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: string;
ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK: string; ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK: string;
ONBOARDING_PROXY_INSTALL_LINK: string; ONBOARDING_PROXY_INSTALL_LINK: string;
ALLOW_AUTOPLAY: boolean;
} }
export interface RuntimeConfig { export interface RuntimeConfig {
@ -39,6 +40,7 @@ export interface RuntimeConfig {
TURNSTILE_KEY: string | null; TURNSTILE_KEY: string | null;
CDN_REPLACEMENTS: Array<string[]>; CDN_REPLACEMENTS: Array<string[]>;
HAS_ONBOARDING: boolean; HAS_ONBOARDING: boolean;
ALLOW_AUTOPLAY: boolean;
ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: string | null; ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: string | null;
ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK: string | null; ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK: string | null;
ONBOARDING_PROXY_INSTALL_LINK: string | null; ONBOARDING_PROXY_INSTALL_LINK: string | null;
@ -64,6 +66,7 @@ const env: Record<keyof Config, undefined | string> = {
TURNSTILE_KEY: import.meta.env.VITE_TURNSTILE_KEY, TURNSTILE_KEY: import.meta.env.VITE_TURNSTILE_KEY,
CDN_REPLACEMENTS: import.meta.env.VITE_CDN_REPLACEMENTS, CDN_REPLACEMENTS: import.meta.env.VITE_CDN_REPLACEMENTS,
HAS_ONBOARDING: import.meta.env.VITE_HAS_ONBOARDING, HAS_ONBOARDING: import.meta.env.VITE_HAS_ONBOARDING,
ALLOW_AUTOPLAY: import.meta.env.VITE_ALLOW_AUTOPLAY,
}; };
function coerceUndefined(value: string | null | undefined): string | undefined { function coerceUndefined(value: string | null | undefined): string | undefined {
@ -109,6 +112,7 @@ export function conf(): RuntimeConfig {
.filter((v) => v.length > 0), .filter((v) => v.length > 0),
NORMAL_ROUTER: getKey("NORMAL_ROUTER", "false") === "true", NORMAL_ROUTER: getKey("NORMAL_ROUTER", "false") === "true",
HAS_ONBOARDING: getKey("HAS_ONBOARDING", "true") === "true", HAS_ONBOARDING: getKey("HAS_ONBOARDING", "true") === "true",
ALLOW_AUTOPLAY: getKey("ALLOW_AUTOPLAY", "false") === "true",
TURNSTILE_KEY: getKey("TURNSTILE_KEY"), TURNSTILE_KEY: getKey("TURNSTILE_KEY"),
DISALLOWED_IDS: getKey("DISALLOWED_IDS", "") DISALLOWED_IDS: getKey("DISALLOWED_IDS", "")
.split(",") .split(",")