v2: global player, infinite scroll, image picker, threaded comments
This commit is contained in:
62
src/components/GlobalPlayer.tsx
Normal file
62
src/components/GlobalPlayer.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { useContext, useEffect, useRef, useState } from "react";
|
||||
import { PlayerContext } from "../contexts/PlayerContext.ts";
|
||||
|
||||
export function GlobalPlayer() {
|
||||
const { current, stop } = useContext(PlayerContext);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [reduced, setReduced] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!current) {
|
||||
document.body.classList.remove("has-player");
|
||||
document.body.style.removeProperty("--player-height");
|
||||
return;
|
||||
}
|
||||
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
|
||||
document.body.style.setProperty("--player-height", `${el.offsetHeight}px`);
|
||||
document.body.classList.add("has-player");
|
||||
|
||||
const observer = new ResizeObserver(() => {
|
||||
document.body.style.setProperty("--player-height", `${el.offsetHeight}px`);
|
||||
});
|
||||
observer.observe(el);
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
document.body.classList.remove("has-player");
|
||||
document.body.style.removeProperty("--player-height");
|
||||
};
|
||||
}, [current]);
|
||||
|
||||
useEffect(() => {
|
||||
if (current) setReduced(false);
|
||||
}, [current?.embedUrl]);
|
||||
|
||||
if (!current) return null;
|
||||
|
||||
return (
|
||||
<div className={`global-player global-player--${current.type}${reduced ? " global-player--reduced" : ""}`} ref={ref}>
|
||||
<div className="global-player-header">
|
||||
<span className="global-player-title">{current.title ?? current.embedUrl}</span>
|
||||
<button className="btn btn--ghost" onClick={() => setReduced((r) => !r)}>
|
||||
{reduced ? "▲" : "▼"}
|
||||
</button>
|
||||
<button className="btn btn--ghost" onClick={stop}>
|
||||
✕
|
||||
</button>
|
||||
</div>
|
||||
<div className="global-player-body">
|
||||
<div className="global-player-iframe-wrap">
|
||||
<iframe
|
||||
src={current.embedUrl}
|
||||
className={`global-player-iframe--${current.type}`}
|
||||
allow="autoplay; encrypted-media"
|
||||
allowFullScreen
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user