diff --git a/src/index.tsx b/src/index.tsx
index b30b7595..a49d556a 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -10,12 +10,12 @@ import { ErrorBoundary } from "@/pages/errors/ErrorBoundary";
import App from "@/setup/App";
import { conf } from "@/setup/config";
import i18n from "@/setup/i18n";
-
import "@/setup/ga";
import "@/setup/index.css";
+import { useLanguageStore } from "@/stores/language";
+
import { initializeChromecast } from "./setup/chromecast";
-import { SettingsStore } from "./state/settings/store";
-import { initializeStores } from "./utils/storage";
+import { initializeOldStores } from "./stores/__old/migrations";
// initialize
const key =
@@ -29,8 +29,8 @@ registerSW({
});
const LazyLoadedApp = React.lazy(async () => {
- await initializeStores();
- i18n.changeLanguage(SettingsStore.get().language ?? "en");
+ await initializeOldStores();
+ i18n.changeLanguage(useLanguageStore.getState().language);
return {
default: App,
};
diff --git a/src/setup/App.tsx b/src/setup/App.tsx
index c09c816e..2bca1e51 100644
--- a/src/setup/App.tsx
+++ b/src/setup/App.tsx
@@ -19,10 +19,8 @@ import { HomePage } from "@/pages/HomePage";
import { PlayerView } from "@/pages/PlayerView";
import { SettingsPage } from "@/pages/Settings";
import { Layout } from "@/setup/Layout";
-import { BookmarkContextProvider } from "@/state/bookmark";
-import { SettingsProvider } from "@/state/settings";
-import { WatchedContextProvider } from "@/state/watched";
import { useHistoryListener } from "@/stores/history";
+import { useLanguageListener } from "@/stores/language";
function LegacyUrlView({ children }: { children: ReactElement }) {
const location = useLocation();
@@ -60,83 +58,66 @@ function QuickSearch() {
function App() {
useHistoryListener();
useOnlineListener();
+ useLanguageListener();
return (
-
-
-
-
-
- {/* functional routes */}
-
-
-
-
-
-
-
- {({ match }) => {
- if (match?.params.query)
- return (
-
- );
- return ;
- }}
-
+
+
+ {/* functional routes */}
+
+
+
+
+
+
+
+ {({ match }) => {
+ if (match?.params.query)
+ return (
+
+ );
+ return ;
+ }}
+
- {/* pages */}
-
-
-
-
-
-
-
-
+ {/* pages */}
+
+
+
+
+
+
+
+
- {/* Settings page */}
-
+ {/* Settings page */}
+
- {/* admin routes */}
-
+ {/* admin routes */}
+
- {/* other */}
- import("@/pages/DeveloperPage"))}
- />
- import("@/pages/developer/VideoTesterView")
- )}
- />
- {/* developer routes that can abuse workers are disabled in production */}
- {process.env.NODE_ENV === "development" ? (
- import("@/pages/developer/TestView"))}
- />
- ) : null}
-
-
-
-
-
-
+ {/* other */}
+ import("@/pages/DeveloperPage"))}
+ />
+ import("@/pages/developer/VideoTesterView"))}
+ />
+ {/* developer routes that can abuse workers are disabled in production */}
+ {process.env.NODE_ENV === "development" ? (
+ import("@/pages/developer/TestView"))}
+ />
+ ) : null}
+
+
+
);
}
diff --git a/src/state/bookmark/context.tsx b/src/state/bookmark/context.tsx
deleted file mode 100644
index 692d4e76..00000000
--- a/src/state/bookmark/context.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import { ReactNode, createContext, useContext, useMemo } from "react";
-
-import { MWMediaMeta } from "@/backend/metadata/types/mw";
-import { useStore } from "@/utils/storage";
-
-import { BookmarkStore } from "./store";
-import { BookmarkStoreData } from "./types";
-
-interface BookmarkStoreDataWrapper {
- setItemBookmark(media: MWMediaMeta, bookedmarked: boolean): void;
- getFilteredBookmarks(): MWMediaMeta[];
- bookmarkStore: BookmarkStoreData;
-}
-
-const BookmarkedContext = createContext({
- setItemBookmark: () => {},
- getFilteredBookmarks: () => [],
- bookmarkStore: {
- bookmarks: [],
- },
-});
-
-function getBookmarkIndexFromMedia(
- bookmarks: MWMediaMeta[],
- media: MWMediaMeta
-): number {
- const a = bookmarks.findIndex((v) => v.id === media.id);
- return a;
-}
-
-export function BookmarkContextProvider(props: { children: ReactNode }) {
- const [bookmarkStorage, setBookmarked] = useStore(BookmarkStore);
-
- const contextValue = useMemo(
- () => ({
- setItemBookmark(media: MWMediaMeta, bookmarked: boolean) {
- setBookmarked((data: BookmarkStoreData): BookmarkStoreData => {
- let bookmarks = [...data.bookmarks];
- bookmarks = bookmarks.filter((v) => v.id !== media.id);
- if (bookmarked) bookmarks.push({ ...media });
- return {
- bookmarks,
- };
- });
- },
- getFilteredBookmarks() {
- return [...bookmarkStorage.bookmarks];
- },
- bookmarkStore: bookmarkStorage,
- }),
- [bookmarkStorage, setBookmarked]
- );
-
- return (
-
- {props.children}
-
- );
-}
-
-export function useBookmarkContext() {
- return useContext(BookmarkedContext);
-}
-
-export function getIfBookmarkedFromPortable(
- bookmarks: MWMediaMeta[],
- media: MWMediaMeta
-): boolean {
- const bookmarked = getBookmarkIndexFromMedia(bookmarks, media);
- return bookmarked !== -1;
-}
diff --git a/src/state/bookmark/index.ts b/src/state/bookmark/index.ts
deleted file mode 100644
index 2edd280c..00000000
--- a/src/state/bookmark/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./context";
diff --git a/src/state/settings/context.tsx b/src/state/settings/context.tsx
deleted file mode 100644
index 4810f925..00000000
--- a/src/state/settings/context.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import { ReactNode, createContext, useContext, useMemo } from "react";
-
-import { LangCode } from "@/setup/iso6391";
-import { useStore } from "@/utils/storage";
-
-import { SettingsStore } from "./store";
-import { MWSettingsData } from "./types";
-
-interface MWSettingsDataSetters {
- setLanguage(language: LangCode): void;
- setCaptionLanguage(language: LangCode): void;
- setCaptionDelay(delay: number): void;
- setCaptionColor(color: string): void;
- setCaptionFontSize(size: number): void;
- setCaptionBackgroundColor(backgroundColor: number): void;
-}
-type MWSettingsDataWrapper = MWSettingsData & MWSettingsDataSetters;
-const SettingsContext = createContext(null as any);
-export function SettingsProvider(props: { children: ReactNode }) {
- function enforceRange(min: number, value: number, max: number) {
- return Math.max(min, Math.min(value, max));
- }
- const [settings, setSettings] = useStore(SettingsStore);
- const context: MWSettingsDataWrapper = useMemo(() => {
- const settingsContext: MWSettingsDataWrapper = {
- ...settings,
- setLanguage(language) {
- setSettings((oldSettings) => {
- return {
- ...oldSettings,
- language,
- };
- });
- },
- setCaptionLanguage(language) {
- setSettings((oldSettings) => {
- const captionSettings = oldSettings.captionSettings;
- captionSettings.language = language;
- const newSettings = oldSettings;
- return newSettings;
- });
- },
- setCaptionDelay(delay: number) {
- setSettings((oldSettings) => {
- const captionSettings = oldSettings.captionSettings;
- captionSettings.delay = enforceRange(-10, delay, 10);
- const newSettings = oldSettings;
- return newSettings;
- });
- },
- setCaptionColor(color) {
- setSettings((oldSettings) => {
- const style = oldSettings.captionSettings.style;
- style.color = color;
- const newSettings = oldSettings;
- return newSettings;
- });
- },
- setCaptionFontSize(size) {
- setSettings((oldSettings) => {
- const style = oldSettings.captionSettings.style;
- style.fontSize = enforceRange(10, size, 60);
- const newSettings = oldSettings;
- return newSettings;
- });
- },
- setCaptionBackgroundColor(backgroundColor) {
- setSettings((oldSettings) => {
- const style = oldSettings.captionSettings.style;
- style.backgroundColor = `${style.backgroundColor.substring(
- 0,
- 7
- )}${backgroundColor.toString(16).padStart(2, "0")}`;
- const newSettings = oldSettings;
- return newSettings;
- });
- },
- };
- return settingsContext;
- }, [settings, setSettings]);
- return (
-
- {props.children}
-
- );
-}
-
-export function useSettings() {
- return useContext(SettingsContext);
-}
-
-export default SettingsContext;
diff --git a/src/state/settings/index.ts b/src/state/settings/index.ts
deleted file mode 100644
index 2edd280c..00000000
--- a/src/state/settings/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./context";
diff --git a/src/state/settings/store.ts b/src/state/settings/store.ts
deleted file mode 100644
index 19d84e15..00000000
--- a/src/state/settings/store.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { createVersionedStore } from "@/utils/storage";
-
-import { MWSettingsData, MWSettingsDataV1 } from "./types";
-
-export const SettingsStore = createVersionedStore()
- .setKey("mw-settings")
- .addVersion({
- version: 0,
- create(): MWSettingsDataV1 {
- return {
- language: "en",
- captionSettings: {
- delay: 0,
- style: {
- color: "#ffffff",
- fontSize: 25,
- backgroundColor: "#00000096",
- },
- },
- };
- },
- migrate(data: MWSettingsDataV1): MWSettingsData {
- return {
- language: data.language,
- captionSettings: {
- language: "none",
- ...data.captionSettings,
- },
- };
- },
- })
- .addVersion({
- version: 1,
- create(): MWSettingsData {
- return {
- language: "en",
- captionSettings: {
- delay: 0,
- language: "none",
- style: {
- color: "#ffffff",
- fontSize: 25,
- backgroundColor: "#00000096",
- },
- },
- };
- },
- })
- .build();
diff --git a/src/state/watched/context.tsx b/src/state/watched/context.tsx
deleted file mode 100644
index 661b0ed3..00000000
--- a/src/state/watched/context.tsx
+++ /dev/null
@@ -1,204 +0,0 @@
-import {
- ReactNode,
- createContext,
- useCallback,
- useContext,
- useMemo,
- useRef,
-} from "react";
-
-import { DetailedMeta } from "@/backend/metadata/getmeta";
-import { MWMediaType } from "@/backend/metadata/types/mw";
-import { useStore } from "@/utils/storage";
-
-import { VideoProgressStore } from "./store";
-import { StoreMediaItem, WatchedStoreData, WatchedStoreItem } from "./types";
-
-const FIVETEEN_MINUTES = 15 * 60;
-const FIVE_MINUTES = 5 * 60;
-
-function shouldSave(
- time: number,
- duration: number,
- isSeries: boolean
-): boolean {
- const timeFromEnd = Math.max(0, duration - time);
-
- // short movie
- if (duration < FIVETEEN_MINUTES) {
- if (time < 5) return false;
- if (timeFromEnd < 60) return false;
- return true;
- }
-
- // long movie
- if (time < 30) return false;
- if (timeFromEnd < FIVE_MINUTES && !isSeries) return false;
- return true;
-}
-
-interface WatchedStoreDataWrapper {
- updateProgress(media: StoreMediaItem, progress: number, total: number): void;
- getFilteredWatched(): WatchedStoreItem[];
- removeProgress(id: string): void;
- watched: WatchedStoreData;
-}
-
-const WatchedContext = createContext({
- updateProgress: () => {},
- getFilteredWatched: () => [],
- removeProgress: () => {},
- watched: {
- items: [],
- },
-});
-WatchedContext.displayName = "WatchedContext";
-
-function isSameEpisode(media: StoreMediaItem, v: StoreMediaItem) {
- return (
- media.meta.id === v.meta.id &&
- (!media.series ||
- (media.series.seasonId === v.series?.seasonId &&
- media.series.episodeId === v.series?.episodeId))
- );
-}
-
-export function WatchedContextProvider(props: { children: ReactNode }) {
- const [watched, setWatched] = useStore(VideoProgressStore);
-
- const contextValue = useMemo(
- () => ({
- removeProgress(id: string) {
- setWatched((data: WatchedStoreData) => {
- const newData = { ...data };
- newData.items = newData.items.filter((v) => v.item.meta.id !== id);
- return newData;
- });
- },
- updateProgress(
- media: StoreMediaItem,
- progress: number,
- total: number
- ): void {
- setWatched((data: WatchedStoreData) => {
- const newData = { ...data };
- let item = newData.items.find((v) => isSameEpisode(media, v.item));
- if (!item) {
- item = {
- item: {
- ...media,
- meta: { ...media.meta },
- series: media.series ? { ...media.series } : undefined,
- },
- progress: 0,
- percentage: 0,
- watchedAt: Date.now(),
- };
- newData.items.push(item);
- }
- // update actual item
- item.progress = progress;
- item.percentage = Math.round((progress / total) * 100);
- item.watchedAt = Date.now();
-
- // remove item if shouldnt save
- if (!shouldSave(progress, total, !!media.series)) {
- newData.items = data.items.filter(
- (v) => !isSameEpisode(v.item, media)
- );
- }
-
- return newData;
- });
- },
- getFilteredWatched() {
- let filtered = watched.items;
-
- // get most recently watched for every single item
- const alreadyFoundMedia: string[] = [];
- filtered = filtered
- .sort((a, b) => {
- return b.watchedAt - a.watchedAt;
- })
- .filter((item) => {
- const mediaId = item.item.meta.id;
- if (alreadyFoundMedia.includes(mediaId)) return false;
- alreadyFoundMedia.push(mediaId);
- return true;
- });
- return filtered;
- },
- watched,
- }),
- [watched, setWatched]
- );
-
- return (
-
- {props.children}
-
- );
-}
-
-export function useWatchedContext() {
- return useContext(WatchedContext);
-}
-
-function isSameEpisodeMeta(
- media: StoreMediaItem,
- mediaTwo: DetailedMeta | null,
- episodeId?: string
-) {
- if (mediaTwo?.meta.type === MWMediaType.SERIES && episodeId) {
- return isSameEpisode(media, {
- meta: mediaTwo.meta,
- series: {
- season: 0,
- episode: 0,
- episodeId,
- seasonId: mediaTwo.meta.seasonData.id,
- },
- });
- }
- if (!mediaTwo) return () => false;
- return isSameEpisode(media, { meta: mediaTwo.meta });
-}
-
-export function useWatchedItem(meta: DetailedMeta | null, episodeId?: string) {
- const { watched, updateProgress } = useContext(WatchedContext);
- const item = useMemo(
- () => watched.items.find((v) => isSameEpisodeMeta(v.item, meta, episodeId)),
- [watched, meta, episodeId]
- );
- const lastCommitedTime = useRef([0, 0]);
-
- const callback = useCallback(
- (progress: number, total: number) => {
- const hasChanged =
- lastCommitedTime.current[0] !== progress ||
- lastCommitedTime.current[1] !== total;
- if (meta && hasChanged) {
- lastCommitedTime.current = [progress, total];
- const obj = {
- meta: meta.meta,
- series:
- meta.meta.type === MWMediaType.SERIES && episodeId
- ? {
- seasonId: meta.meta.seasonData.id,
- episodeId,
- season: meta.meta.seasonData.number,
- episode:
- meta.meta.seasonData.episodes.find(
- (ep) => ep.id === episodeId
- )?.number || 0,
- }
- : undefined,
- };
- updateProgress(obj, progress, total);
- }
- },
- [meta, updateProgress, episodeId]
- );
-
- return { updateProgress: callback, watchedItem: item };
-}
diff --git a/src/state/watched/index.ts b/src/state/watched/index.ts
deleted file mode 100644
index 2edd280c..00000000
--- a/src/state/watched/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./context";
diff --git a/src/state/bookmark/store.ts b/src/stores/__old/bookmark/store.ts
similarity index 96%
rename from src/state/bookmark/store.ts
rename to src/stores/__old/bookmark/store.ts
index 3d68afec..8a1a0f02 100644
--- a/src/state/bookmark/store.ts
+++ b/src/stores/__old/bookmark/store.ts
@@ -1,8 +1,8 @@
import { MWMediaType } from "@/backend/metadata/types/mw";
import { BookmarkMediaItem, useBookmarkStore } from "@/stores/bookmarks";
-import { createVersionedStore } from "@/utils/storage";
import { BookmarkStoreData } from "./types";
+import { createVersionedStore } from "../migrations";
import { OldBookmarks, migrateV1Bookmarks } from "../watched/migrations/v2";
import { migrateV2Bookmarks } from "../watched/migrations/v3";
diff --git a/src/state/bookmark/types.ts b/src/stores/__old/bookmark/types.ts
similarity index 100%
rename from src/state/bookmark/types.ts
rename to src/stores/__old/bookmark/types.ts
diff --git a/src/utils/storage.ts b/src/stores/__old/migrations.ts
similarity index 90%
rename from src/utils/storage.ts
rename to src/stores/__old/migrations.ts
index 83057d54..e79113ca 100644
--- a/src/utils/storage.ts
+++ b/src/stores/__old/migrations.ts
@@ -1,5 +1,3 @@
-import { useEffect, useState } from "react";
-
interface StoreVersion {
version: number;
migrate?(data: A): any;
@@ -28,7 +26,7 @@ interface InternalStoreData {
const storeCallbacks: Record void)[]> = {};
const stores: Record, InternalStoreData]> = {};
-export async function initializeStores() {
+export async function initializeOldStores() {
// migrate all stores
for (const [store, internal] of Object.values(stores)) {
const versions = internal.versions.sort((a, b) => a.version - b.version);
@@ -177,24 +175,3 @@ export function createVersionedStore(): StoreBuilder {
},
};
}
-
-export function useStore(
- store: StoreRet
-): [T, (cb: (old: T) => T) => void] {
- const [data, setData] = useState(store.get());
- useEffect(() => {
- const { destroy } = store.onChange((newData) => {
- setData(newData);
- });
- return () => {
- destroy();
- };
- }, [store]);
-
- function setNewData(cb: (old: T) => T) {
- const newData = cb(data);
- store.save(newData);
- }
-
- return [data, setNewData];
-}
diff --git a/src/stores/__old/settings/store.ts b/src/stores/__old/settings/store.ts
new file mode 100644
index 00000000..2f92d3ba
--- /dev/null
+++ b/src/stores/__old/settings/store.ts
@@ -0,0 +1,68 @@
+import { useLanguageStore } from "@/stores/language";
+import { useSubtitleStore } from "@/stores/subtitles";
+
+import { MWSettingsData, MWSettingsDataV1 } from "./types";
+import { createVersionedStore } from "../migrations";
+
+export const SettingsStore = createVersionedStore>()
+ .setKey("mw-settings")
+ .addVersion({
+ version: 0,
+ create(): MWSettingsDataV1 {
+ return {
+ language: "en",
+ captionSettings: {
+ delay: 0,
+ style: {
+ color: "#ffffff",
+ fontSize: 25,
+ backgroundColor: "#00000096",
+ },
+ },
+ };
+ },
+ migrate(data: MWSettingsDataV1): MWSettingsData {
+ return {
+ language: data.language,
+ captionSettings: {
+ language: "none",
+ ...data.captionSettings,
+ },
+ };
+ },
+ })
+ .addVersion({
+ version: 1,
+ migrate(old: MWSettingsData): Record {
+ const langStore = useLanguageStore.getState();
+ const subtitleStore = useSubtitleStore.getState();
+
+ const backgroundColor = old.captionSettings.style.backgroundColor;
+ let backgroundOpacity = 0.5;
+ if (backgroundColor.length === 9) {
+ const opacitySplit = backgroundColor.slice(7); // '#' + 6 digits
+ backgroundOpacity = parseInt(opacitySplit, 16) / 255; // read as hex;
+ }
+
+ langStore.setLanguage(old.language);
+ subtitleStore.updateStyling({
+ backgroundOpacity,
+ color: old.captionSettings.style.color,
+ size: old.captionSettings.style.fontSize / 25,
+ });
+ subtitleStore.importSubtitleLanguage(
+ old.captionSettings.language === "none"
+ ? null
+ : old.captionSettings.language
+ );
+
+ return {};
+ },
+ })
+ .addVersion({
+ version: 2,
+ create(): Record {
+ return {};
+ },
+ })
+ .build();
diff --git a/src/state/settings/types.ts b/src/stores/__old/settings/types.ts
similarity index 100%
rename from src/state/settings/types.ts
rename to src/stores/__old/settings/types.ts
diff --git a/src/stores/__old/volume/store.ts b/src/stores/__old/volume/store.ts
new file mode 100644
index 00000000..9c2eeba1
--- /dev/null
+++ b/src/stores/__old/volume/store.ts
@@ -0,0 +1,29 @@
+import { useVolumeStore } from "@/stores/volume";
+
+import { createVersionedStore } from "../migrations";
+
+interface VolumeStoreData {
+ volume: number;
+}
+
+export const volumeStore = createVersionedStore>()
+ .setKey("mw-volume")
+ .addVersion({
+ version: 0,
+ create() {
+ return {
+ volume: 1,
+ };
+ },
+ migrate(data: VolumeStoreData): Record {
+ useVolumeStore.getState().setVolume(data.volume);
+ return {};
+ },
+ })
+ .addVersion({
+ version: 1,
+ create() {
+ return {};
+ },
+ })
+ .build();
diff --git a/src/state/watched/migrations/v2.ts b/src/stores/__old/watched/migrations/v2.ts
similarity index 100%
rename from src/state/watched/migrations/v2.ts
rename to src/stores/__old/watched/migrations/v2.ts
diff --git a/src/state/watched/migrations/v3.ts b/src/stores/__old/watched/migrations/v3.ts
similarity index 100%
rename from src/state/watched/migrations/v3.ts
rename to src/stores/__old/watched/migrations/v3.ts
diff --git a/src/state/watched/migrations/v4.ts b/src/stores/__old/watched/migrations/v4.ts
similarity index 100%
rename from src/state/watched/migrations/v4.ts
rename to src/stores/__old/watched/migrations/v4.ts
diff --git a/src/state/watched/store.ts b/src/stores/__old/watched/store.ts
similarity index 95%
rename from src/state/watched/store.ts
rename to src/stores/__old/watched/store.ts
index 75d05b93..7d5739ad 100644
--- a/src/state/watched/store.ts
+++ b/src/stores/__old/watched/store.ts
@@ -1,10 +1,10 @@
import { useProgressStore } from "@/stores/progress";
-import { createVersionedStore } from "@/utils/storage";
import { OldData, migrateV2Videos } from "./migrations/v2";
import { migrateV3Videos } from "./migrations/v3";
import { migrateV4Videos } from "./migrations/v4";
import { WatchedStoreData } from "./types";
+import { createVersionedStore } from "../migrations";
export const VideoProgressStore = createVersionedStore()
.setKey("video-progress")
diff --git a/src/state/watched/types.ts b/src/stores/__old/watched/types.ts
similarity index 100%
rename from src/state/watched/types.ts
rename to src/stores/__old/watched/types.ts
diff --git a/src/stores/language/index.ts b/src/stores/language/index.ts
new file mode 100644
index 00000000..9ff91476
--- /dev/null
+++ b/src/stores/language/index.ts
@@ -0,0 +1,29 @@
+import { useEffect } from "react";
+import { create } from "zustand";
+import { immer } from "zustand/middleware/immer";
+
+import i18n from "@/setup/i18n";
+
+export interface LanguageStore {
+ language: string;
+ setLanguage(v: string): void;
+}
+
+export const useLanguageStore = create(
+ immer((set) => ({
+ language: "en",
+ setLanguage(v) {
+ set((s) => {
+ s.language = v;
+ });
+ },
+ }))
+);
+
+export function useLanguageListener() {
+ const language = useLanguageStore((s) => s.language);
+
+ useEffect(() => {
+ i18n.changeLanguage(language);
+ }, [language]);
+}
diff --git a/src/stores/subtitles/index.ts b/src/stores/subtitles/index.ts
index 9a7f1e86..6bf93737 100644
--- a/src/stores/subtitles/index.ts
+++ b/src/stores/subtitles/index.ts
@@ -30,9 +30,9 @@ export interface SubtitleStore {
setCustomSubs(): void;
setOverrideCasing(enabled: boolean): void;
setDelay(delay: number): void;
+ importSubtitleLanguage(lang: string | null): void;
}
-// TODO add migration from previous stored settings
export const useSubtitleStore = create(
persist(
immer((set) => ({
@@ -77,6 +77,11 @@ export const useSubtitleStore = create(
s.delay = Math.max(Math.min(500, delay), -500);
});
},
+ importSubtitleLanguage(lang) {
+ set((s) => {
+ s.lastSelectedLanguage = lang;
+ });
+ },
})),
{
name: "__MW::subtitles",