diff --git a/src/components/FlagIcon.tsx b/src/components/FlagIcon.tsx
new file mode 100644
index 00000000..fcfd1531
--- /dev/null
+++ b/src/components/FlagIcon.tsx
@@ -0,0 +1,17 @@
+import classNames from "classnames";
+import "flag-icons/css/flag-icons.min.css";
+
+export interface FlagIconProps {
+ countryCode?: string;
+}
+
+export function FlagIcon(props: FlagIconProps) {
+ return (
+
+ );
+}
diff --git a/src/components/player/atoms/Settings.tsx b/src/components/player/atoms/Settings.tsx
index 9b0f7173..7c0cbfa3 100644
--- a/src/components/player/atoms/Settings.tsx
+++ b/src/components/player/atoms/Settings.tsx
@@ -1,256 +1,27 @@
-import "flag-icons/css/flag-icons.min.css";
+import { useEffect } from "react";
-import classNames from "classnames";
-import { useCallback, useEffect, useState } from "react";
-
-import { Toggle } from "@/components/buttons/Toggle";
-import { Icon, Icons } from "@/components/Icon";
+import { Icons } from "@/components/Icon";
import { OverlayAnchor } from "@/components/overlays/OverlayAnchor";
import { Overlay } from "@/components/overlays/OverlayDisplay";
import { OverlayPage } from "@/components/overlays/OverlayPage";
import { OverlayRouter } from "@/components/overlays/OverlayRouter";
+import { SettingsMenu } from "@/components/player/atoms/settings/SettingsMenu";
+import { SourceSelectionView } from "@/components/player/atoms/settings/SourceSelectingView";
import { VideoPlayerButton } from "@/components/player/internals/Button";
import { Context } from "@/components/player/internals/ContextUtils";
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
import { usePlayerStore } from "@/stores/player/store";
-import {
- SourceQuality,
- allQualities,
- qualityToString,
-} from "@/stores/player/utils/qualities";
-
-function QualityOption(props: {
- children: React.ReactNode;
- selected?: boolean;
- disabled?: boolean;
- onClick?: () => void;
-}) {
- let textClasses;
- if (props.selected) textClasses = "text-white";
- if (props.disabled)
- textClasses = "text-video-context-type-main text-opacity-40";
-
- return (
-
-
- {props.children}
-
- {props.selected ? (
-
- ) : null}
-
- );
-}
-
-function QualityView({ id }: { id: string }) {
- const router = useOverlayRouter(id);
- const availableQualities = usePlayerStore((s) => s.qualities);
- const currentQuality = usePlayerStore((s) => s.currentQuality);
- const switchQuality = usePlayerStore((s) => s.switchQuality);
- const change = useCallback(
- (q: SourceQuality) => {
- switchQuality(q);
- router.close();
- },
- [router, switchQuality]
- );
-
- const allVisibleQualities = allQualities.filter((t) => t !== "unknown");
-
- return (
- <>
- router.navigate("/")}>
- Quality
-
-
- {allVisibleQualities.map((v) => (
- change(v) : undefined
- }
- disabled={!availableQualities.includes(v)}
- >
- {qualityToString(v)}
-
- ))}
-
-
- Automatic quality
- Toggle
-
-
- You can try{" "}
- router.navigate("/source")}>
- switching source
- {" "}
- to get different quality options.
-
-
- >
- );
-}
-
-function ColorOption(props: {
- color: string;
- active?: boolean;
- onClick: () => void;
-}) {
- return (
-
-
- {props.active ? (
-
- ) : null}
-
-
- );
-}
-
-function CaptionSettingsView({ id }: { id: string }) {
- const router = useOverlayRouter(id);
-
- return (
- <>
- router.navigate("/captions")}>
- Custom captions
-
-
-
-
Color
-
- {}} color="#FFFFFF" active />
- {}} color="#80B1FA" />
- {}} color="#E2E535" />
-
-
-
- >
- );
-}
-
-function CaptionOption(props: {
- countryCode?: string;
- children: React.ReactNode;
- selected?: boolean;
-}) {
- return (
-
-
-
-
-
- {props.children}
-
- {props.selected ? (
-
- ) : null}
-
- );
-}
-
-function CaptionsView({ id }: { id: string }) {
- const router = useOverlayRouter(id);
-
- return (
- <>
- router.navigate("/")}
- rightSide={
-
- }
- >
- Captions
-
-
- Off
-
- Nederlands
-
- Idk Gibraltar of zo?
-
- >
- );
-}
+import { CaptionSettingsView } from "./settings/CaptionSettingsView";
+import { CaptionsView } from "./settings/CaptionsView";
+import { QualityView } from "./settings/QualityView";
function SettingsOverlay({ id }: { id: string }) {
- const router = useOverlayRouter(id);
- const currentQuality = usePlayerStore((s) => s.currentQuality);
-
- const [tmpBool, setTmpBool] = useState(false);
-
- function toggleBool() {
- setTmpBool(!tmpBool);
- }
-
return (
-
- Video settings
-
- router.navigate("/quality")}>
- Quality
-
- {currentQuality ? qualityToString(currentQuality) : ""}
-
-
- router.navigate("/source")}>
- Video source
- SuperStream
-
-
- Download
-
-
-
-
- Viewing Experience
-
-
- Enable Captions
- toggleBool()} />
-
- router.navigate("/captions")}>
- Caption settings
- English
-
-
- Playback settings
-
-
-
-
+
@@ -269,10 +40,7 @@ function SettingsOverlay({ id }: { id: string }) {
- router.navigate("/")}>
- It's a minion!
-
-
+
diff --git a/src/components/player/atoms/settings/CaptionSettingsView.tsx b/src/components/player/atoms/settings/CaptionSettingsView.tsx
new file mode 100644
index 00000000..012d85fc
--- /dev/null
+++ b/src/components/player/atoms/settings/CaptionSettingsView.tsx
@@ -0,0 +1,52 @@
+import classNames from "classnames";
+
+import { Icon, Icons } from "@/components/Icon";
+import { Context } from "@/components/player/internals/ContextUtils";
+import { useOverlayRouter } from "@/hooks/useOverlayRouter";
+
+export function ColorOption(props: {
+ color: string;
+ active?: boolean;
+ onClick: () => void;
+}) {
+ return (
+
+
+ {props.active ? (
+
+ ) : null}
+
+
+ );
+}
+
+export function CaptionSettingsView({ id }: { id: string }) {
+ const router = useOverlayRouter(id);
+
+ return (
+ <>
+ router.navigate("/captions")}>
+ Custom captions
+
+
+
+
Color
+
+ {}} color="#FFFFFF" active />
+ {}} color="#80B1FA" />
+ {}} color="#E2E535" />
+
+
+
+ >
+ );
+}
diff --git a/src/components/player/atoms/settings/CaptionsView.tsx b/src/components/player/atoms/settings/CaptionsView.tsx
new file mode 100644
index 00000000..30ad36ea
--- /dev/null
+++ b/src/components/player/atoms/settings/CaptionsView.tsx
@@ -0,0 +1,60 @@
+import classNames from "classnames";
+
+import { FlagIcon } from "@/components/FlagIcon";
+import { Icon, Icons } from "@/components/Icon";
+import { Context } from "@/components/player/internals/ContextUtils";
+import { useOverlayRouter } from "@/hooks/useOverlayRouter";
+
+export function CaptionOption(props: {
+ countryCode?: string;
+ children: React.ReactNode;
+ selected?: boolean;
+}) {
+ return (
+
+
+
+
+
+ {props.children}
+
+ {props.selected ? (
+
+ ) : null}
+
+ );
+}
+
+export function CaptionsView({ id }: { id: string }) {
+ const router = useOverlayRouter(id);
+
+ return (
+ <>
+ router.navigate("/")}
+ rightSide={
+
+ }
+ >
+ Captions
+
+
+ Off
+
+ Nederlands
+
+ Idk Gibraltar of zo?
+
+ >
+ );
+}
diff --git a/src/components/player/atoms/settings/QualityView.tsx b/src/components/player/atoms/settings/QualityView.tsx
new file mode 100644
index 00000000..4808dde2
--- /dev/null
+++ b/src/components/player/atoms/settings/QualityView.tsx
@@ -0,0 +1,88 @@
+import { useCallback } from "react";
+
+import { Icon, Icons } from "@/components/Icon";
+import { Context } from "@/components/player/internals/ContextUtils";
+import { useOverlayRouter } from "@/hooks/useOverlayRouter";
+import { usePlayerStore } from "@/stores/player/store";
+import {
+ SourceQuality,
+ allQualities,
+ qualityToString,
+} from "@/stores/player/utils/qualities";
+
+export function QualityOption(props: {
+ children: React.ReactNode;
+ selected?: boolean;
+ disabled?: boolean;
+ onClick?: () => void;
+}) {
+ let textClasses;
+ if (props.selected) textClasses = "text-white";
+ if (props.disabled)
+ textClasses = "text-video-context-type-main text-opacity-40";
+
+ return (
+
+
+ {props.children}
+
+ {props.selected ? (
+
+ ) : null}
+
+ );
+}
+
+export function QualityView({ id }: { id: string }) {
+ const router = useOverlayRouter(id);
+ const availableQualities = usePlayerStore((s) => s.qualities);
+ const currentQuality = usePlayerStore((s) => s.currentQuality);
+ const switchQuality = usePlayerStore((s) => s.switchQuality);
+
+ const change = useCallback(
+ (q: SourceQuality) => {
+ switchQuality(q);
+ router.close();
+ },
+ [router, switchQuality]
+ );
+
+ const allVisibleQualities = allQualities.filter((t) => t !== "unknown");
+
+ return (
+ <>
+ router.navigate("/")}>
+ Quality
+
+
+ {allVisibleQualities.map((v) => (
+ change(v) : undefined
+ }
+ disabled={!availableQualities.includes(v)}
+ >
+ {qualityToString(v)}
+
+ ))}
+
+
+ Automatic quality
+ Toggle
+
+
+ You can try{" "}
+ router.navigate("/source")}>
+ switching source
+ {" "}
+ to get different quality options.
+
+
+ >
+ );
+}
diff --git a/src/components/player/atoms/settings/SettingsMenu.tsx b/src/components/player/atoms/settings/SettingsMenu.tsx
new file mode 100644
index 00000000..861418c8
--- /dev/null
+++ b/src/components/player/atoms/settings/SettingsMenu.tsx
@@ -0,0 +1,57 @@
+import { useState } from "react";
+
+import { Toggle } from "@/components/buttons/Toggle";
+import { Icons } from "@/components/Icon";
+import { Context } from "@/components/player/internals/ContextUtils";
+import { useOverlayRouter } from "@/hooks/useOverlayRouter";
+import { usePlayerStore } from "@/stores/player/store";
+import { qualityToString } from "@/stores/player/utils/qualities";
+
+export function SettingsMenu({ id }: { id: string }) {
+ const router = useOverlayRouter(id);
+ const currentQuality = usePlayerStore((s) => s.currentQuality);
+
+ const [tmpBool, setTmpBool] = useState(false);
+
+ function toggleBool() {
+ setTmpBool(!tmpBool);
+ }
+
+ return (
+
+ Video settings
+
+ router.navigate("/quality")}>
+ Quality
+
+ {currentQuality ? qualityToString(currentQuality) : ""}
+
+
+ router.navigate("/source")}>
+ Video source
+ SuperStream
+
+
+ Download
+
+
+
+
+ Viewing Experience
+
+
+ Enable Captions
+ toggleBool()} />
+
+ router.navigate("/captions")}>
+ Caption settings
+ English
+
+
+ Playback settings
+
+
+
+
+ );
+}
diff --git a/src/components/player/atoms/settings/SourceSelectingView.tsx b/src/components/player/atoms/settings/SourceSelectingView.tsx
new file mode 100644
index 00000000..ba439387
--- /dev/null
+++ b/src/components/player/atoms/settings/SourceSelectingView.tsx
@@ -0,0 +1,57 @@
+import classNames from "classnames";
+import { useMemo } from "react";
+
+import { Icon, Icons } from "@/components/Icon";
+import { Context } from "@/components/player/internals/ContextUtils";
+import { useOverlayRouter } from "@/hooks/useOverlayRouter";
+import { usePlayerStore } from "@/stores/player/store";
+import { providers } from "@/utils/providers";
+
+export function SourceOption(props: {
+ children: React.ReactNode;
+ selected?: boolean;
+ onClick?: () => void;
+}) {
+ return (
+
+
+ {props.children}
+
+ {props.selected ? (
+
+ ) : null}
+
+ );
+}
+
+export function SourceSelectionView({ id }: { id: string }) {
+ const router = useOverlayRouter(id);
+ const metaType = usePlayerStore((s) => s.meta?.type);
+ const sources = useMemo(() => {
+ if (!metaType) return [];
+ return providers
+ .listSources()
+ .filter((v) => v.mediaTypes?.includes(metaType));
+ }, [metaType]);
+
+ return (
+ <>
+ router.navigate("/")}>
+ Sources
+
+
+ {sources.map((v) => (
+ {v.name}
+ ))}
+
+ >
+ );
+}