diff --git a/index.html b/index.html
index 5c674b2f..8ab66908 100644
--- a/index.html
+++ b/index.html
@@ -19,7 +19,7 @@
diff --git a/src/components/overlays/OverlayPage.tsx b/src/components/overlays/OverlayPage.tsx
index af4c7d03..db582395 100644
--- a/src/components/overlays/OverlayPage.tsx
+++ b/src/components/overlays/OverlayPage.tsx
@@ -44,10 +44,7 @@ export function OverlayPage(props: Props) {
show={show}
>
- {props.children}
+
+
+
+
+ {props.children}
+
+
);
}
diff --git a/src/components/player/atoms/Settings.tsx b/src/components/player/atoms/Settings.tsx
index 7f372767..1556a2de 100644
--- a/src/components/player/atoms/Settings.tsx
+++ b/src/components/player/atoms/Settings.tsx
@@ -6,15 +6,41 @@ import { Overlay } from "@/components/overlays/OverlayDisplay";
import { OverlayPage } from "@/components/overlays/OverlayPage";
import { OverlayRouter } from "@/components/overlays/OverlayRouter";
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";
function SettingsOverlay({ id }: { id: string }) {
+ const router = useOverlayRouter("settings");
+
return (
-
- This is settings menu, welcome!
+
+
+ Ba ba ba ba my title
+
+ Hi
+ router.navigate("/other")}>
+ Go to page 2
+
+
+
+ Video source
+ SuperStream
+
+
+
+
+
+
+ Some other bit
+
+
+
+
diff --git a/src/components/player/base/BackLink.tsx b/src/components/player/base/BackLink.tsx
index 56f97044..27e0255d 100644
--- a/src/components/player/base/BackLink.tsx
+++ b/src/components/player/base/BackLink.tsx
@@ -1,16 +1,16 @@
import { useTranslation } from "react-i18next";
+import { useHistory } from "react-router-dom";
import { Icon, Icons } from "@/components/Icon";
-import { useGoBack } from "@/hooks/useGoBack";
-export function BackLink() {
+export function BackLink(props: { url: string }) {
const { t } = useTranslation();
- const goBack = useGoBack();
+ const history = useHistory();
return (
goBack()}
+ onClick={() => history.push(props.url)}
className="flex items-center cursor-pointer text-type-secondary hover:text-white transition-colors duration-200 font-medium"
>
diff --git a/src/components/player/hooks/usePlayer.ts b/src/components/player/hooks/usePlayer.ts
index 8da2664c..02e3801f 100644
--- a/src/components/player/hooks/usePlayer.ts
+++ b/src/components/player/hooks/usePlayer.ts
@@ -13,9 +13,11 @@ export function usePlayer() {
const setMeta = usePlayerStore((s) => s.setMeta);
const status = usePlayerStore((s) => s.status);
const display = usePlayerStore((s) => s.display);
+ const reset = usePlayerStore((s) => s.reset);
const { init } = useInitializePlayer();
return {
+ reset,
status,
setMeta(meta: PlayerMeta) {
setMeta(meta);
diff --git a/src/components/player/internals/ContextUtils.tsx b/src/components/player/internals/ContextUtils.tsx
new file mode 100644
index 00000000..1aa460b1
--- /dev/null
+++ b/src/components/player/internals/ContextUtils.tsx
@@ -0,0 +1,56 @@
+import { Icon, Icons } from "@/components/Icon";
+
+function Card(props: { children: React.ReactNode }) {
+ return {props.children}
;
+}
+
+function Title(props: { children: React.ReactNode }) {
+ return (
+
+ {props.children}
+
+ );
+}
+
+function Section(props: { children: React.ReactNode }) {
+ return {props.children}
;
+}
+
+function Link(props: { onClick?: () => void; children: React.ReactNode }) {
+ return (
+
+ );
+}
+
+function LinkTitle(props: { children: React.ReactNode }) {
+ return (
+
+ {props.children}
+
+ );
+}
+
+function LinkChevron(props: { children?: React.ReactNode }) {
+ return (
+
+ {props.children}
+
+
+ );
+}
+
+export const Context = {
+ Card,
+ Title,
+ Section,
+ Link,
+ LinkTitle,
+ LinkChevron,
+};
diff --git a/src/hooks/useOverlayRouter.ts b/src/hooks/useOverlayRouter.ts
index 046156de..a83815c5 100644
--- a/src/hooks/useOverlayRouter.ts
+++ b/src/hooks/useOverlayRouter.ts
@@ -56,9 +56,9 @@ export function useInternalOverlayRouter(id: string) {
}
const close = useCallback(() => {
+ if (route) setRoute(null);
setTransition(null);
- setRoute(null);
- }, [setRoute, setTransition]);
+ }, [setRoute, route, setTransition]);
const open = useCallback(() => {
const anchor = document.getElementById(`__overlayRouter::${id}`);
diff --git a/src/pages/PlayerView.tsx b/src/pages/PlayerView.tsx
index a73d5cca..7d6b8067 100644
--- a/src/pages/PlayerView.tsx
+++ b/src/pages/PlayerView.tsx
@@ -1,13 +1,11 @@
import { RunOutput } from "@movie-web/providers";
-import { useCallback } from "react";
+import { useCallback, useEffect, useState } from "react";
import { useParams } from "react-router-dom";
-import { useAsync } from "react-use";
import { MWStreamType } from "@/backend/helpers/streams";
-import { getMetaFromId } from "@/backend/metadata/getmeta";
-import { decodeTMDBId } from "@/backend/metadata/tmdb";
import { usePlayer } from "@/components/player/hooks/usePlayer";
import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta";
+import { MetaPart } from "@/pages/parts/player/MetaPart";
import { PlayerPart } from "@/pages/parts/player/PlayerPart";
import { ScrapingPart } from "@/pages/parts/player/ScrapingPart";
import { playerStatus } from "@/stores/player/slices/source";
@@ -18,18 +16,13 @@ export function PlayerView() {
episode?: string;
season?: string;
}>();
- const { status, playMedia } = usePlayer();
+ const { status, playMedia, reset } = usePlayer();
const { setPlayerMeta, scrapeMedia } = usePlayerMeta();
+ const [backUrl] = useState("/");
- const { loading, error } = useAsync(async () => {
- const data = decodeTMDBId(params.media);
- if (!data) return;
-
- const meta = await getMetaFromId(data.type, data.id, params.season);
- if (!meta) return;
-
- setPlayerMeta(meta);
- }, []);
+ useEffect(() => {
+ reset();
+ }, [params.media, reset]);
const playAfterScrape = useCallback(
(out: RunOutput | null) => {
@@ -57,12 +50,9 @@ export function PlayerView() {
);
return (
-
+
{status === playerStatus.IDLE ? (
-
- {loading ?
loading meta...
: null}
- {error ?
failed to load meta!
: null}
-
+
) : null}
{status === playerStatus.SCRAPING && scrapeMedia ? (
diff --git a/src/pages/parts/player/MetaPart.tsx b/src/pages/parts/player/MetaPart.tsx
new file mode 100644
index 00000000..9efdc0dd
--- /dev/null
+++ b/src/pages/parts/player/MetaPart.tsx
@@ -0,0 +1,54 @@
+import { useHistory, useParams } from "react-router-dom";
+import { useAsync } from "react-use";
+
+import { DetailedMeta, getMetaFromId } from "@/backend/metadata/getmeta";
+import { decodeTMDBId } from "@/backend/metadata/tmdb";
+import { MWMediaType } from "@/backend/metadata/types/mw";
+
+export interface MetaPartProps {
+ onGetMeta?: (meta: DetailedMeta, episodeId?: string) => void;
+}
+
+export function MetaPart(props: MetaPartProps) {
+ const params = useParams<{
+ media: string;
+ episode?: string;
+ season?: string;
+ }>();
+ const history = useHistory();
+
+ const { loading, error } = useAsync(async () => {
+ const data = decodeTMDBId(params.media);
+ if (!data) return;
+
+ const meta = await getMetaFromId(data.type, data.id, params.season);
+ if (!meta) return;
+
+ // replace link with new link if youre not already on the right link
+ let epId = params.episode;
+ if (meta.meta.type === MWMediaType.SERIES) {
+ let ep = meta.meta.seasonData.episodes.find(
+ (v) => v.id === params.episode
+ );
+ if (!ep) ep = meta.meta.seasonData.episodes[0];
+ epId = ep.id;
+ if (
+ params.season !== meta.meta.seasonData.id ||
+ params.episode !== ep.id
+ ) {
+ history.replace(
+ `/media/${params.media}/${meta.meta.seasonData.id}/${ep.id}`
+ );
+ }
+ }
+
+ props.onGetMeta?.(meta, epId);
+ }, []);
+
+ return (
+
+ {loading ?
loading meta...
: null}
+ {error ?
failed to load meta!
: null}
+
+ );
+}
diff --git a/src/pages/parts/player/PlayerPart.tsx b/src/pages/parts/player/PlayerPart.tsx
index 62092009..91d6f5d3 100644
--- a/src/pages/parts/player/PlayerPart.tsx
+++ b/src/pages/parts/player/PlayerPart.tsx
@@ -6,6 +6,7 @@ import { useShouldShowControls } from "@/components/player/hooks/useShouldShowCo
export interface PlayerPartProps {
children?: ReactNode;
+ backUrl: string;
onLoad?: () => void;
}
@@ -34,7 +35,7 @@ export function PlayerPart(props: PlayerPartProps) {
-
+
/
diff --git a/src/setup/App.tsx b/src/setup/App.tsx
index 840b612b..4d063fa5 100644
--- a/src/setup/App.tsx
+++ b/src/setup/App.tsx
@@ -67,13 +67,18 @@ function App() {
-
+
{({ match }) => {
if (match?.params.query)
- return ;
- return ;
+ return (
+
+ );
+ return ;
}}
diff --git a/src/stores/player/slices/display.ts b/src/stores/player/slices/display.ts
index bb2645bd..e2ced531 100644
--- a/src/stores/player/slices/display.ts
+++ b/src/stores/player/slices/display.ts
@@ -1,9 +1,11 @@
import { DisplayInterface } from "@/components/player/display/displayInterface";
+import { playerStatus } from "@/stores/player/slices/source";
import { MakeSlice } from "@/stores/player/slices/types";
export interface DisplaySlice {
display: DisplayInterface | null;
setDisplay(display: DisplayInterface | null): void;
+ reset(): void;
}
export const createDisplaySlice: MakeSlice
= (set, get) => ({
@@ -68,4 +70,11 @@ export const createDisplaySlice: MakeSlice = (set, get) => ({
s.display = newDisplay;
});
},
+ reset() {
+ get().display?.destroy();
+ set((s) => {
+ s.status = playerStatus.IDLE;
+ s.meta = null;
+ });
+ },
});
diff --git a/tailwind.config.js b/tailwind.config.js
index ff9650a7..d2eb0a07 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -123,6 +123,17 @@ module.exports = {
audio: {
set: "#A75FC9"
+ },
+
+ context: {
+ background: "#0C1216",
+ light: "#4D79A8",
+ border: "#4F5C66",
+
+ type: {
+ main: "#617A8A",
+ secondary: "#374A56"
+ }
}
}
}