mirror of
https://github.com/zadam/trilium.git
synced 2026-03-13 20:03:36 +01:00
feat(audio): introduce loop button
This commit is contained in:
parent
6b974c2ac7
commit
e86d84c463
@ -3,7 +3,7 @@ import { useRef, useState } from "preact/hooks";
|
||||
import FNote from "../../../entities/fnote";
|
||||
import { t } from "../../../services/i18n";
|
||||
import { getUrlForDownload } from "../../../services/open";
|
||||
import { PlayPauseButton, SeekBar, SkipButton, VolumeControl } from "./MediaPlayer";
|
||||
import { LoopButton, PlayPauseButton, SeekBar, SkipButton, VolumeControl } from "./MediaPlayer";
|
||||
|
||||
export default function AudioPreview({ note }: { note: FNote }) {
|
||||
const [playing, setPlaying] = useState(false);
|
||||
@ -25,9 +25,11 @@ export default function AudioPreview({ note }: { note: FNote }) {
|
||||
<div className="left" />
|
||||
|
||||
<div className="center">
|
||||
<div className="spacer" />
|
||||
<SkipButton mediaRef={audioRef} seconds={-10} icon="bx bx-rewind" text={t("video.back-10s")} />
|
||||
<PlayPauseButton mediaRef={audioRef} playing={playing} />
|
||||
<SkipButton mediaRef={audioRef} seconds={30} icon="bx bx-fast-forward" text={t("video.forward-30s")} />
|
||||
<LoopButton mediaRef={audioRef} />
|
||||
</div>
|
||||
|
||||
<div className="right">
|
||||
|
||||
@ -146,3 +146,33 @@ export function SkipButton({ mediaRef, seconds, icon, text }: { mediaRef: RefObj
|
||||
<ActionButton icon={icon} text={text} onClick={skip} />
|
||||
);
|
||||
}
|
||||
|
||||
export function LoopButton({ mediaRef }: { mediaRef: RefObject<HTMLVideoElement | HTMLAudioElement> }) {
|
||||
const [loop, setLoop] = useState(() => mediaRef.current?.loop ?? false);
|
||||
|
||||
useEffect(() => {
|
||||
const media = mediaRef.current;
|
||||
if (!media) return;
|
||||
setLoop(media.loop);
|
||||
|
||||
const observer = new MutationObserver(() => setLoop(media.loop));
|
||||
observer.observe(media, { attributes: true, attributeFilter: ["loop"] });
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
const toggle = () => {
|
||||
const media = mediaRef.current;
|
||||
if (!media) return;
|
||||
media.loop = !media.loop;
|
||||
setLoop(media.loop);
|
||||
};
|
||||
|
||||
return (
|
||||
<ActionButton
|
||||
className={loop ? "active" : ""}
|
||||
icon="bx bx-repeat"
|
||||
text={loop ? t("video.disable-loop") : t("video.loop")}
|
||||
onClick={toggle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import ActionButton from "../../react/ActionButton";
|
||||
import Dropdown from "../../react/Dropdown";
|
||||
import Icon from "../../react/Icon";
|
||||
import NoItems from "../../react/NoItems";
|
||||
import { PlayPauseButton, SeekBar, SkipButton, VolumeControl } from "./MediaPlayer";
|
||||
import { LoopButton, PlayPauseButton, SeekBar, SkipButton, VolumeControl } from "./MediaPlayer";
|
||||
|
||||
const AUTO_HIDE_DELAY = 3000;
|
||||
|
||||
@ -125,7 +125,7 @@ export default function VideoPreview({ note }: { note: FNote }) {
|
||||
<SkipButton mediaRef={videoRef} seconds={-10} icon="bx bx-rewind" text={t("video.back-10s")} />
|
||||
<PlayPauseButton mediaRef={videoRef} playing={playing} />
|
||||
<SkipButton mediaRef={videoRef} seconds={30} icon="bx bx-fast-forward" text={t("video.forward-30s")} />
|
||||
<LoopButton videoRef={videoRef} />
|
||||
<LoopButton mediaRef={videoRef} />
|
||||
</div>
|
||||
<div className="right">
|
||||
<VolumeControl mediaRef={videoRef} />
|
||||
@ -217,36 +217,6 @@ function PlaybackSpeed({ videoRef }: { videoRef: RefObject<HTMLVideoElement> })
|
||||
);
|
||||
}
|
||||
|
||||
function LoopButton({ videoRef }: { videoRef: RefObject<HTMLVideoElement> }) {
|
||||
const [loop, setLoop] = useState(() => videoRef.current?.loop ?? false);
|
||||
|
||||
useEffect(() => {
|
||||
const video = videoRef.current;
|
||||
if (!video) return;
|
||||
setLoop(video.loop);
|
||||
|
||||
const observer = new MutationObserver(() => setLoop(video.loop));
|
||||
observer.observe(video, { attributes: true, attributeFilter: ["loop"] });
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
const toggle = () => {
|
||||
const video = videoRef.current;
|
||||
if (!video) return;
|
||||
video.loop = !video.loop;
|
||||
setLoop(video.loop);
|
||||
};
|
||||
|
||||
return (
|
||||
<ActionButton
|
||||
className={loop ? "active" : ""}
|
||||
icon="bx bx-repeat"
|
||||
text={loop ? t("video.disable-loop") : t("video.loop")}
|
||||
onClick={toggle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function RotateButton({ videoRef }: { videoRef: RefObject<HTMLVideoElement> }) {
|
||||
const [rotation, setRotation] = useState(0);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user