From f588dbed5b5b4df1fc1827ef9ce4cb94bc7bd12a Mon Sep 17 00:00:00 2001
From: lavafrai <lavafrai@yandex.ru>
Date: Wed, 4 Dec 2024 23:47:36 +0300
Subject: [PATCH 1/2] feat: saving the user's preferred voiceover

---
 .../ReleasePlayer/ReleasePlayer.tsx           | 15 ++++++++--
 app/store/voiceover.ts                        | 28 +++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 app/store/voiceover.ts

diff --git a/app/components/ReleasePlayer/ReleasePlayer.tsx b/app/components/ReleasePlayer/ReleasePlayer.tsx
index 11bfd6e..a3b16f4 100644
--- a/app/components/ReleasePlayer/ReleasePlayer.tsx
+++ b/app/components/ReleasePlayer/ReleasePlayer.tsx
@@ -2,6 +2,7 @@
 
 import { Spinner } from "#/components/Spinner/Spinner";
 import { useUserStore } from "#/store/auth";
+import { useVoiceoverStore } from "#/store/voiceover";
 import { Card, Dropdown, Button } from "flowbite-react";
 import { ENDPOINTS } from "#/api/config";
 import { useState, useEffect } from "react";
@@ -139,20 +140,30 @@ const saveAnonEpisodeWatched = (
 
 export const ReleasePlayer = (props: { id: number }) => {
   const userStore = useUserStore();
+  const preferredVoiceoverStore = useVoiceoverStore();
+  const storedPreferredVoiceover = preferredVoiceoverStore.getPreferredVoiceover(props.id);
   const [voiceoverInfo, setVoiceoverInfo] = useState(null);
   const [selectedVoiceover, setSelectedVoiceover] = useState(null);
   const [sourcesInfo, setSourcesInfo] = useState(null);
   const [selectedSource, setSelectedSource] = useState(null);
   const [episodeInfo, setEpisodeInfo] = useState(null);
   const [selectedEpisode, setSelectedEpisode] = useState(null);
+  const setSelectedVoiceoverAndSaveAsPreferred = (voiceover: any) => {
+    setSelectedVoiceover(voiceover);
+    preferredVoiceoverStore.setPreferredVoiceover(props.id, voiceover.name);
+  }
 
   useEffect(() => {
     async function _fetchInfo() {
       const voiceover = await _fetch(
         `${ENDPOINTS.release.episode}/${props.id}`
       );
+      const preferredVoiceover = voiceover.types.find(
+        (voiceover: any) => voiceover.name === storedPreferredVoiceover
+      ) || voiceover.types[0];
+
       setVoiceoverInfo(voiceover.types);
-      setSelectedVoiceover(voiceover.types[0]);
+      setSelectedVoiceover(preferredVoiceover);
     }
     _fetchInfo();
     // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -227,7 +238,7 @@ export const ReleasePlayer = (props: { id: number }) => {
               {voiceoverInfo.map((voiceover: any) => (
                 <Dropdown.Item
                   key={`voiceover_${voiceover.id}`}
-                  onClick={() => setSelectedVoiceover(voiceover)}
+                  onClick={() => setSelectedVoiceoverAndSaveAsPreferred(voiceover)}
                 >
                   {voiceover.name}
                 </Dropdown.Item>
diff --git a/app/store/voiceover.ts b/app/store/voiceover.ts
new file mode 100644
index 0000000..e60f033
--- /dev/null
+++ b/app/store/voiceover.ts
@@ -0,0 +1,28 @@
+"use client";
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+
+interface voiceoverState {
+    preferences: Map<number, string>;
+    getPreferredVoiceover: (id: number) => (string | undefined);
+    setPreferredVoiceover: (id: number, voiceover: string) => void;
+}
+
+export const useVoiceoverStore = create<voiceoverState>()(
+    persist(
+        (set, get) => ({
+            preferences: new Map<number, string>(),
+            getPreferredVoiceover: (id: number) => get().preferences[id],
+            setPreferredVoiceover: (id: number, voiceover: string) => {
+                let current = get().preferences
+                current[id] = voiceover
+                set({
+                    preferences: current,
+                });
+            },
+        }),
+        {
+            name: "voiceover-preferences",
+        }
+    )
+);
\ No newline at end of file

From 70e4d7a523db9e62336f31ddba02d73a1e5208f7 Mon Sep 17 00:00:00 2001
From: lavafrai <lavafrai@yandex.ru>
Date: Thu, 5 Dec 2024 00:12:23 +0300
Subject: [PATCH 2/2] feat: saving the user's preferred video source

---
 .../ReleasePlayer/ReleasePlayer.tsx           | 17 ++++++--
 app/store/player.ts                           | 42 +++++++++++++++++++
 app/store/voiceover.ts                        | 28 -------------
 3 files changed, 55 insertions(+), 32 deletions(-)
 create mode 100644 app/store/player.ts
 delete mode 100644 app/store/voiceover.ts

diff --git a/app/components/ReleasePlayer/ReleasePlayer.tsx b/app/components/ReleasePlayer/ReleasePlayer.tsx
index a3b16f4..0e74655 100644
--- a/app/components/ReleasePlayer/ReleasePlayer.tsx
+++ b/app/components/ReleasePlayer/ReleasePlayer.tsx
@@ -2,7 +2,7 @@
 
 import { Spinner } from "#/components/Spinner/Spinner";
 import { useUserStore } from "#/store/auth";
-import { useVoiceoverStore } from "#/store/voiceover";
+import { useUserPlayerPreferencesStore } from "#/store/player";
 import { Card, Dropdown, Button } from "flowbite-react";
 import { ENDPOINTS } from "#/api/config";
 import { useState, useEffect } from "react";
@@ -140,8 +140,9 @@ const saveAnonEpisodeWatched = (
 
 export const ReleasePlayer = (props: { id: number }) => {
   const userStore = useUserStore();
-  const preferredVoiceoverStore = useVoiceoverStore();
+  const preferredVoiceoverStore = useUserPlayerPreferencesStore();
   const storedPreferredVoiceover = preferredVoiceoverStore.getPreferredVoiceover(props.id);
+  const storedPreferredPlayer = preferredVoiceoverStore.getPreferredPlayer(props.id);
   const [voiceoverInfo, setVoiceoverInfo] = useState(null);
   const [selectedVoiceover, setSelectedVoiceover] = useState(null);
   const [sourcesInfo, setSourcesInfo] = useState(null);
@@ -152,6 +153,10 @@ export const ReleasePlayer = (props: { id: number }) => {
     setSelectedVoiceover(voiceover);
     preferredVoiceoverStore.setPreferredVoiceover(props.id, voiceover.name);
   }
+  const setSelectedPlayerAndSaveAsPreferred = (player: any) => {
+    setSelectedSource(player);
+    preferredVoiceoverStore.setPreferredPlayer(props.id, player.name);
+  }
 
   useEffect(() => {
     async function _fetchInfo() {
@@ -174,8 +179,12 @@ export const ReleasePlayer = (props: { id: number }) => {
       const sources = await _fetch(
         `${ENDPOINTS.release.episode}/${props.id}/${selectedVoiceover.id}`
       );
+      const preferredSource = sources.sources.find(
+        (source: any) => source.name === storedPreferredPlayer
+      ) || sources.sources[0];
+
       setSourcesInfo(sources.sources);
-      setSelectedSource(sources.sources[0]);
+      setSelectedSource(preferredSource);
     }
     if (selectedVoiceover) {
       _fetchInfo();
@@ -252,7 +261,7 @@ export const ReleasePlayer = (props: { id: number }) => {
               {sourcesInfo.map((source: any) => (
                 <Dropdown.Item
                   key={`source_${source.id}`}
-                  onClick={() => setSelectedSource(source)}
+                  onClick={() => setSelectedPlayerAndSaveAsPreferred(source)}
                 >
                   {source.name}
                 </Dropdown.Item>
diff --git a/app/store/player.ts b/app/store/player.ts
new file mode 100644
index 0000000..eb92dad
--- /dev/null
+++ b/app/store/player.ts
@@ -0,0 +1,42 @@
+"use client";
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+
+interface userPlayerPreferencesState {
+    voiceover: Map<number, string>;
+    player: Map<number, string>;
+    getPreferredVoiceover: (id: number) => (string | undefined);
+    setPreferredVoiceover: (id: number, voiceover: string) => void;
+    getPreferredPlayer: (id: number) => (string | undefined);
+    setPreferredPlayer: (id: number, player: string) => void;
+}
+
+export const useUserPlayerPreferencesStore = create<userPlayerPreferencesState>()(
+    persist(
+        (set, get) => ({
+            voiceover: new Map<number, string>(),
+            player: new Map<number, string>(),
+            getPreferredVoiceover: (id: number) => get().voiceover[id],
+            setPreferredVoiceover: (id: number, voiceover: string) => {
+                let current = get().voiceover
+                current[id] = voiceover
+                set({
+                    voiceover: current,
+                    player: get().player,
+                });
+            },
+            getPreferredPlayer: (id: number) => get().player[id],
+            setPreferredPlayer: (id: number, player: string) => {
+                let current = get().player
+                current[id] = player
+                set({
+                    voiceover: get().voiceover,
+                    player: current,
+                })
+            }
+        }),
+        {
+            name: "player-preferences",
+        }
+    )
+);
\ No newline at end of file
diff --git a/app/store/voiceover.ts b/app/store/voiceover.ts
deleted file mode 100644
index e60f033..0000000
--- a/app/store/voiceover.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-"use client";
-import { create } from "zustand";
-import { persist } from "zustand/middleware";
-
-interface voiceoverState {
-    preferences: Map<number, string>;
-    getPreferredVoiceover: (id: number) => (string | undefined);
-    setPreferredVoiceover: (id: number, voiceover: string) => void;
-}
-
-export const useVoiceoverStore = create<voiceoverState>()(
-    persist(
-        (set, get) => ({
-            preferences: new Map<number, string>(),
-            getPreferredVoiceover: (id: number) => get().preferences[id],
-            setPreferredVoiceover: (id: number, voiceover: string) => {
-                let current = get().preferences
-                current[id] = voiceover
-                set({
-                    preferences: current,
-                });
-            },
-        }),
-        {
-            name: "voiceover-preferences",
-        }
-    )
-);
\ No newline at end of file