40 lines
1.6 KiB
TypeScript
40 lines
1.6 KiB
TypeScript
import { lazy, Suspense, useState } from "react";
|
|
import { useQueryClient } from "@tanstack/react-query";
|
|
import { type Video, type VideoStatus } from "../../lib/api";
|
|
import { qk } from "../../lib/queryKeys";
|
|
import { notifyActionError } from "../../lib/actionErrors";
|
|
import { useStableCallback } from "../../lib/useLatest";
|
|
import { writeVideoState } from "../video/videoWrites";
|
|
import { useOpenLinkedPlayer } from "./useOpenLinkedPlayer";
|
|
import { msg } from "../../lib/notifications";
|
|
|
|
const PlayerModal = lazy(() => import("./PlayerModal"));
|
|
|
|
/** The shell's player, for an address that names one over a page that hosts none of its own (the
|
|
* channel manager, where the watched-videos dialog played it; any page a link names): the video
|
|
* alone. Decided at boot, once — `hosted` is whether the page on screen then opens it itself. */
|
|
export function LinkedPlayer({ hosted }: { hosted: boolean }) {
|
|
const qc = useQueryClient();
|
|
const [own] = useState(!hosted);
|
|
const [video, setVideo] = useState<Video | null>(null);
|
|
useOpenLinkedPlayer(
|
|
own,
|
|
() => undefined,
|
|
(v) => setVideo(v),
|
|
);
|
|
const onState = useStableCallback((id: string, status: VideoStatus) => {
|
|
const write = writeVideoState(qc, id, status);
|
|
write
|
|
.then(() => qc.invalidateQueries({ queryKey: qk.feed() }))
|
|
.catch((e: unknown) => notifyActionError(e, msg("errors.writeFailed.videoState")));
|
|
return write;
|
|
});
|
|
const close = useStableCallback(() => setVideo(null));
|
|
if (!video) return null;
|
|
return (
|
|
<Suspense fallback={null}>
|
|
<PlayerModal video={video} startAt={null} onClose={close} onState={onState} />
|
|
</Suspense>
|
|
);
|
|
}
|