@@ -266,6 +272,8 @@ export function SettingsPage() {
setLanguage={state.appLanguage.set}
enableThumbnails={state.enableThumbnails.state}
setEnableThumbnails={state.enableThumbnails.set}
+ enableAutoplay={state.enableAutoplay.state}
+ setEnableAutoplay={state.enableAutoplay.set}
/>
diff --git a/src/pages/parts/settings/PreferencesPart.tsx b/src/pages/parts/settings/PreferencesPart.tsx
index 2c1c5f37..71f9c5f8 100644
--- a/src/pages/parts/settings/PreferencesPart.tsx
+++ b/src/pages/parts/settings/PreferencesPart.tsx
@@ -1,3 +1,4 @@
+import classNames from "classnames";
import { useTranslation } from "react-i18next";
import { Toggle } from "@/components/buttons/Toggle";
@@ -5,6 +6,7 @@ import { FlagIcon } from "@/components/FlagIcon";
import { Dropdown } from "@/components/form/Dropdown";
import { Heading1 } from "@/components/utils/Text";
import { appLanguageOptions } from "@/setup/i18n";
+import { isAutoplayAllowed } from "@/utils/autoplay";
import { getLocaleInfo, sortLangCodes } from "@/utils/language";
export function PreferencesPart(props: {
@@ -12,10 +14,14 @@ export function PreferencesPart(props: {
setLanguage: (l: string) => void;
enableThumbnails: boolean;
setEnableThumbnails: (v: boolean) => void;
+ enableAutoplay: boolean;
+ setEnableAutoplay: (v: boolean) => void;
}) {
const { t } = useTranslation();
const sorted = sortLangCodes(appLanguageOptions.map((item) => item.code));
+ const allowAutoplay = isAutoplayAllowed();
+
const options = appLanguageOptions
.sort((a, b) => sorted.indexOf(a.code) - sorted.indexOf(b.code))
.map((opt) => ({
@@ -62,6 +68,32 @@ export function PreferencesPart(props: {
+
+
+ {t("settings.preferences.autoplay")}
+
+
+ {t("settings.preferences.autoplayDescription")}
+
+
+ allowAutoplay
+ ? props.setEnableAutoplay(!props.enableAutoplay)
+ : null
+ }
+ className={classNames(
+ "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",
+ allowAutoplay
+ ? "cursor-pointer opacity-100 pointer-events-auto"
+ : "cursor-not-allowed opacity-50 pointer-events-none",
+ )}
+ >
+
+
+ {t("settings.preferences.autoplayLabel")}
+
+
+
);
}
diff --git a/src/setup/config.ts b/src/setup/config.ts
index a71b997c..751540e3 100644
--- a/src/setup/config.ts
+++ b/src/setup/config.ts
@@ -23,6 +23,7 @@ interface Config {
ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: string;
ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK: string;
ONBOARDING_PROXY_INSTALL_LINK: string;
+ ALLOW_AUTOPLAY: boolean;
}
export interface RuntimeConfig {
@@ -39,6 +40,7 @@ export interface RuntimeConfig {
TURNSTILE_KEY: string | null;
CDN_REPLACEMENTS: Array;
HAS_ONBOARDING: boolean;
+ ALLOW_AUTOPLAY: boolean;
ONBOARDING_CHROME_EXTENSION_INSTALL_LINK: string | null;
ONBOARDING_FIREFOX_EXTENSION_INSTALL_LINK: string | null;
ONBOARDING_PROXY_INSTALL_LINK: string | null;
@@ -64,6 +66,7 @@ const env: Record = {
TURNSTILE_KEY: import.meta.env.VITE_TURNSTILE_KEY,
CDN_REPLACEMENTS: import.meta.env.VITE_CDN_REPLACEMENTS,
HAS_ONBOARDING: import.meta.env.VITE_HAS_ONBOARDING,
+ ALLOW_AUTOPLAY: import.meta.env.VITE_ALLOW_AUTOPLAY,
};
function coerceUndefined(value: string | null | undefined): string | undefined {
@@ -109,6 +112,7 @@ export function conf(): RuntimeConfig {
.filter((v) => v.length > 0),
NORMAL_ROUTER: getKey("NORMAL_ROUTER", "false") === "true",
HAS_ONBOARDING: getKey("HAS_ONBOARDING", "true") === "true",
+ ALLOW_AUTOPLAY: getKey("ALLOW_AUTOPLAY", "false") === "true",
TURNSTILE_KEY: getKey("TURNSTILE_KEY"),
DISALLOWED_IDS: getKey("DISALLOWED_IDS", "")
.split(",")
diff --git a/src/stores/player/slices/source.ts b/src/stores/player/slices/source.ts
index eb2ce9e1..5cbfc6db 100644
--- a/src/stores/player/slices/source.ts
+++ b/src/stores/player/slices/source.ts
@@ -169,6 +169,8 @@ export const createSourceSlice: MakeSlice = (set, get) => ({
s.captionList = captions;
s.interface.error = undefined;
s.status = playerStatus.PLAYING;
+ s.audioTracks = [];
+ s.currentAudioTrack = null;
});
const store = get();
store.redisplaySource(startAt);
diff --git a/src/stores/preferences/index.tsx b/src/stores/preferences/index.tsx
index 65fae22d..ce198388 100644
--- a/src/stores/preferences/index.tsx
+++ b/src/stores/preferences/index.tsx
@@ -5,6 +5,8 @@ import { immer } from "zustand/middleware/immer";
export interface PreferencesStore {
enableThumbnails: boolean;
setEnableThumbnails(v: boolean): void;
+ enableAutoplay: boolean;
+ setEnableAutoplay(v: boolean): void;
}
export const usePreferencesStore = create(
@@ -16,6 +18,12 @@ export const usePreferencesStore = create(
s.enableThumbnails = v;
});
},
+ enableAutoplay: false,
+ setEnableAutoplay(v) {
+ set((s) => {
+ s.enableAutoplay = v;
+ });
+ },
})),
{
name: "__MW::preferences",
diff --git a/src/utils/autoplay.ts b/src/utils/autoplay.ts
new file mode 100644
index 00000000..aee01ffb
--- /dev/null
+++ b/src/utils/autoplay.ts
@@ -0,0 +1,11 @@
+import { isExtensionActiveCached } from "@/backend/extension/messaging";
+import { conf } from "@/setup/config";
+import { useAuthStore } from "@/stores/auth";
+
+export function isAutoplayAllowed() {
+ return Boolean(
+ conf().ALLOW_AUTOPLAY ||
+ isExtensionActiveCached() ||
+ useAuthStore.getState().proxySet,
+ );
+}