+
{props.children}
);
}
+interface PopoutListEntryTypes {
+ active?: boolean;
+ children: React.ReactNode;
+ onClick?: () => void;
+ isOnDarkBackground?: boolean;
+ percentageCompleted?: number;
+}
+
+function PopoutListEntry(props: PopoutListEntryTypes) {
+ const bg = props.isOnDarkBackground ? "bg-ash-200" : "bg-ash-400";
+ const hover = props.isOnDarkBackground
+ ? "hover:bg-ash-200"
+ : "hover:bg-ash-400";
+
+ return (
+
+ {props.active && (
+
+ )}
+
{props.children}
+
+
+ {props.percentageCompleted ? (
+
90 ? 100 : props.percentageCompleted
+ }
+ />
+ ) : (
+ ""
+ )}
+
+
+ );
+}
+
export function EpisodeSelectionPopout() {
const params = useParams<{
media: string;
@@ -90,80 +142,113 @@ export function EpisodeSelectionPopout() {
setCurrentVisibleSeason({ seasonId: id });
};
- if (isPickingSeason)
- return (
- <>
-
- Pick a season
-
-
-
- {currentSeasonInfo
- ? meta?.seasons?.map?.((season) => (
-
setSeason(season.id)}
- >
- {season.title}
-
- ))
- : "No season"}
-
-
- >
- );
+ const { watched } = useWatchedContext();
+
+ const titlePositionClass = useMemo(() => {
+ const offset = isPickingSeason ? "left-0" : "left-10";
+ return [
+ "absolute w-full transition-[left,opacity] duration-200",
+ offset,
+ ].join(" ");
+ }, [isPickingSeason]);
return (
<>
-
-
+
+
-
-
- {currentSeasonInfo?.title || ""}
-
-
- {loading ? (
-
-
-
- ) : error ? (
-
-
-
-
- Something went wrong loading the episodes for{" "}
- {currentSeasonInfo?.title?.toLowerCase()}
-
+ {currentSeasonInfo
+ ? meta?.seasons?.map?.((season) => (
+
setSeason(season.id)}
+ isOnDarkBackground
+ >
+ {season.title}
+
+ ))
+ : "No season"}
+
+
+ {loading ? (
+
+
-
- ) : (
-
- {currentSeasonEpisodes && currentSeasonInfo
- ? currentSeasonEpisodes.map((e) => (
-
setCurrent(currentSeasonInfo.id, e.id)}
- key={e.id}
- >
- {e.number}. {e.title}
-
- ))
- : "No episodes"}
-
- )}
-
+ ) : error ? (
+
+
+
+
+ Something went wrong loading the episodes for{" "}
+ {currentSeasonInfo?.title?.toLowerCase()}
+
+
+
+ ) : (
+
+ {currentSeasonEpisodes && currentSeasonInfo
+ ? currentSeasonEpisodes.map((e) => (
+
setCurrent(currentSeasonInfo.id, e.id)}
+ percentageCompleted={
+ watched.items.find(
+ (item) =>
+ item.item?.series?.seasonId ===
+ currentSeasonInfo.id &&
+ item.item?.series?.episodeId === e.id
+ )?.percentage
+ }
+ >
+ E{e.number} - {e.title}
+
+ ))
+ : "No episodes"}
+
+ )}
+
+
>
);
}
diff --git a/src/video/components/popouts/PopoutProviderAction.tsx b/src/video/components/popouts/PopoutProviderAction.tsx
index 0296f416..df71beb4 100644
--- a/src/video/components/popouts/PopoutProviderAction.tsx
+++ b/src/video/components/popouts/PopoutProviderAction.tsx
@@ -1,4 +1,5 @@
import { Transition } from "@/components/Transition";
+import { useSyncPopouts } from "@/video/components/hooks/useSyncPopouts";
import { EpisodeSelectionPopout } from "@/video/components/popouts/EpisodeSelectionPopout";
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
import { useControls } from "@/video/state/logic/controls";
@@ -19,13 +20,12 @@ function ShowPopout(props: { popoutId: string | null }) {
return null;
}
-// TODO use new design for popouts
// TODO improve anti offscreen math
-// TODO attach router history to popout state, so you can use back button to remove popout
export function PopoutProviderAction() {
const descriptor = useVideoPlayerDescriptor();
const videoInterface = useInterface(descriptor);
const controls = useControls(descriptor);
+ useSyncPopouts(descriptor);
const handleClick = useCallback(() => {
controls.closePopout();
@@ -40,12 +40,12 @@ export function PopoutProviderAction() {
30
)}px`
: "30px";
- }, [videoInterface]);
+ }, [videoInterface.popoutBounds]);
const distanceFromBottom = useMemo(() => {
return videoInterface.popoutBounds
? `${videoInterface.popoutBounds.height + 30}px`
: "30px";
- }, [videoInterface]);
+ }, [videoInterface.popoutBounds]);
return (
{!event.errored ? (
-
+
) : (
)}
diff --git a/tailwind.config.js b/tailwind.config.js
index eb70d4d8..e22b3b3a 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -18,7 +18,13 @@ module.exports = {
"denim-400": "#2B263D",
"denim-500": "#38334A",
"denim-600": "#504B64",
- "denim-700": "#7A758F"
+ "denim-700": "#7A758F",
+ "ash-600": "#817998",
+ "ash-500": "#9C93B5",
+ "ash-400": "#3D394D",
+ "ash-300": "#2C293A",
+ "ash-200": "#2B2836",
+ "ash-100": "#1E1C26"
},
/* fonts */