+
diff --git a/src/components/player/atoms/settings/PlaybackSettingsView.tsx b/src/components/player/atoms/settings/PlaybackSettingsView.tsx
index 23bec683..a734e810 100644
--- a/src/components/player/atoms/settings/PlaybackSettingsView.tsx
+++ b/src/components/player/atoms/settings/PlaybackSettingsView.tsx
@@ -47,7 +47,7 @@ export function PlaybackSettingsView({ id }: { id: string }) {
[display]
);
- const options = [0.25, 0.5, 1, 1.25, 2];
+ const options = [0.25, 0.5, 1, 1.5, 2];
return (
<>
diff --git a/src/components/player/hooks/useCaptions.ts b/src/components/player/hooks/useCaptions.ts
index ec99c4fb..b646ee8a 100644
--- a/src/components/player/hooks/useCaptions.ts
+++ b/src/components/player/hooks/useCaptions.ts
@@ -46,10 +46,15 @@ export function useCaptions() {
else await selectLastUsedLanguage();
}, [selectLastUsedLanguage, disable, enabled]);
+ const selectLastUsedLanguageIfEnabled = useCallback(async () => {
+ if (enabled) await selectLastUsedLanguage();
+ }, [selectLastUsedLanguage, enabled]);
+
return {
selectLanguage,
disable,
selectLastUsedLanguage,
toggleLastUsed,
+ selectLastUsedLanguageIfEnabled,
};
}
diff --git a/src/components/player/hooks/useInitializePlayer.ts b/src/components/player/hooks/useInitializePlayer.ts
index 378cdd5e..5964a359 100644
--- a/src/components/player/hooks/useInitializePlayer.ts
+++ b/src/components/player/hooks/useInitializePlayer.ts
@@ -1,8 +1,10 @@
-import { useCallback } from "react";
+import { useCallback, useEffect, useMemo, useRef } from "react";
import { usePlayerStore } from "@/stores/player/store";
import { useVolumeStore } from "@/stores/volume";
+import { useCaptions } from "./useCaptions";
+
export function useInitializePlayer() {
const display = usePlayerStore((s) => s.display);
const volume = useVolumeStore((s) => s.volume);
@@ -15,3 +17,21 @@ export function useInitializePlayer() {
init,
};
}
+
+export function useInitializeSource() {
+ const source = usePlayerStore((s) => s.source);
+ const sourceIdentifier = useMemo(
+ () => (source ? JSON.stringify(source) : null),
+ [source]
+ );
+ const { selectLastUsedLanguageIfEnabled } = useCaptions();
+
+ const funRef = useRef(selectLastUsedLanguageIfEnabled);
+ useEffect(() => {
+ funRef.current = selectLastUsedLanguageIfEnabled;
+ }, [selectLastUsedLanguageIfEnabled]);
+
+ useEffect(() => {
+ if (sourceIdentifier) funRef.current();
+ }, [sourceIdentifier]);
+}
diff --git a/src/components/player/internals/VideoContainer.tsx b/src/components/player/internals/VideoContainer.tsx
index 45476eab..b1282c34 100644
--- a/src/components/player/internals/VideoContainer.tsx
+++ b/src/components/player/internals/VideoContainer.tsx
@@ -5,6 +5,8 @@ import { convertSubtitlesToObjectUrl } from "@/components/player/utils/captions"
import { playerStatus } from "@/stores/player/slices/source";
import { usePlayerStore } from "@/stores/player/store";
+import { useInitializeSource } from "../hooks/useInitializePlayer";
+
// initialize display interface
function useDisplayInterface() {
const display = usePlayerStore((s) => s.display);
@@ -112,6 +114,7 @@ function VideoElement() {
export function VideoContainer() {
const show = useShouldShowVideoElement();
useDisplayInterface();
+ useInitializeSource();
if (!show) return null;
return
;
diff --git a/src/components/text-inputs/AuthInputBox.tsx b/src/components/text-inputs/AuthInputBox.tsx
index 8ff9553e..c79c079d 100644
--- a/src/components/text-inputs/AuthInputBox.tsx
+++ b/src/components/text-inputs/AuthInputBox.tsx
@@ -7,6 +7,7 @@ export function AuthInputBox(props: {
autoComplete?: string;
placeholder?: string;
onChange?: (data: string) => void;
+ passwordToggleable?: boolean;
}) {
return (
@@ -19,6 +20,7 @@ export function AuthInputBox(props: {
autoComplete={props.autoComplete}
onChange={props.onChange}
placeholder={props.placeholder}
+ passwordToggleable={props.passwordToggleable}
className="w-full flex-1 bg-authentication-inputBg px-4 py-3 text-search-text focus:outline-none rounded-lg placeholder:text-gray-700"
/>
diff --git a/src/components/text-inputs/TextInputControl.tsx b/src/components/text-inputs/TextInputControl.tsx
index b555c4f8..91d20c3a 100644
--- a/src/components/text-inputs/TextInputControl.tsx
+++ b/src/components/text-inputs/TextInputControl.tsx
@@ -1,4 +1,7 @@
-import { forwardRef } from "react";
+import classNames from "classnames";
+import { forwardRef, useState } from "react";
+
+import { Icon, Icons } from "../Icon";
export interface TextInputControlPropsNoLabel {
onChange?: (data: string) => void;
@@ -9,6 +12,7 @@ export interface TextInputControlPropsNoLabel {
autoComplete?: string;
placeholder?: string;
className?: string;
+ passwordToggleable?: boolean;
}
export interface TextInputControlProps extends TextInputControlPropsNoLabel {
@@ -30,25 +34,41 @@ export const TextInputControl = forwardRef<
className,
placeholder,
onFocus,
+ passwordToggleable,
},
ref
) => {
+ let inputType = "text";
+ const [showPassword, setShowPassword] = useState(true);
+ if (passwordToggleable) inputType = showPassword ? "password" : "text";
+
const input = (
-
onChange && onChange(e.target.value)}
- value={value}
- name={name}
- autoComplete={autoComplete}
- onBlur={() => onUnFocus && onUnFocus()}
- onFocus={() => onFocus?.()}
- onKeyDown={(e) =>
- e.key === "Enter" ? (e.target as HTMLInputElement).blur() : null
- }
- />
+
+ onChange && onChange(e.target.value)}
+ value={value}
+ name={name}
+ autoComplete={autoComplete}
+ onBlur={() => onUnFocus && onUnFocus()}
+ onFocus={() => onFocus?.()}
+ onKeyDown={(e) =>
+ e.key === "Enter" ? (e.target as HTMLInputElement).blur() : null
+ }
+ />
+ {passwordToggleable ? (
+
+ ) : null}
+
);
if (label) {
diff --git a/src/pages/PlayerView.tsx b/src/pages/PlayerView.tsx
index 37784759..61077177 100644
--- a/src/pages/PlayerView.tsx
+++ b/src/pages/PlayerView.tsx
@@ -1,9 +1,7 @@
import { RunOutput } from "@movie-web/providers";
import { useCallback, useEffect, useState } from "react";
import { useHistory, useParams } from "react-router-dom";
-import { useEffectOnce } from "react-use";
-import { useCaptions } from "@/components/player/hooks/useCaptions";
import { usePlayer } from "@/components/player/hooks/usePlayer";
import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta";
import { convertProviderCaption } from "@/components/player/utils/captions";
@@ -41,7 +39,6 @@ export function PlayerView() {
} = usePlayer();
const { setPlayerMeta, scrapeMedia } = usePlayerMeta();
const backUrl = useLastNonPlayerLink();
- const { disable } = useCaptions();
const paramsData = JSON.stringify({
media: params.media,
@@ -86,10 +83,6 @@ export function PlayerView() {
]
);
- useEffectOnce(() => {
- disable();
- });
-
return (
{status === playerStatus.IDLE ? (
diff --git a/src/pages/parts/auth/LoginFormPart.tsx b/src/pages/parts/auth/LoginFormPart.tsx
index 1ff43422..39b81b96 100644
--- a/src/pages/parts/auth/LoginFormPart.tsx
+++ b/src/pages/parts/auth/LoginFormPart.tsx
@@ -74,6 +74,7 @@ export function LoginFormPart(props: LoginFormPartProps) {
name="username"
onChange={setMnemonic}
placeholder={t("auth.login.passphrasePlaceholder") ?? undefined}
+ passwordToggleable
/>
{result.error ? (
diff --git a/src/stores/history/index.ts b/src/stores/history/index.ts
index 572358cf..8a85f777 100644
--- a/src/stores/history/index.ts
+++ b/src/stores/history/index.ts
@@ -43,11 +43,17 @@ export function useHistoryListener() {
export function useLastNonPlayerLink() {
const routes = useHistoryStore((s) => s.routes);
+ const location = useLocation();
const lastNonPlayerLink = useMemo(() => {
const reversedRoutes = [...routes];
reversedRoutes.reverse();
- const route = reversedRoutes.find((v) => !v.path.startsWith("/media"));
+ const route = reversedRoutes.find(
+ (v) =>
+ !v.path.startsWith("/media") && // cannot be a player link
+ location.pathname !== v.path && // cannot be current link
+ !v.path.startsWith("/s/") // cannot be a quick search link
+ );
return route?.path ?? "/";
- }, [routes]);
+ }, [routes, location]);
return lastNonPlayerLink;
}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index ee5ef13f..913a59fd 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -9,6 +9,11 @@ const config: Config = {
safelist: safeThemeList,
theme: {
extend: {
+ /* breakpoints */
+ screens: {
+ ssm: "400px",
+ },
+
/* fonts */
fontFamily: {
"open-sans": "'Open Sans'",