From 7ba7b98f5fe91ba3f13a877afff08222ca43a82e Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 10 Mar 2026 19:38:15 +0200 Subject: [PATCH] feat(video_player): add playback speed indicator --- .../src/widgets/type_widgets/file/Video.css | 22 +++++++++- .../src/widgets/type_widgets/file/Video.tsx | 43 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/apps/client/src/widgets/type_widgets/file/Video.css b/apps/client/src/widgets/type_widgets/file/Video.css index 39cf2562cf..657f398187 100644 --- a/apps/client/src/widgets/type_widgets/file/Video.css +++ b/apps/client/src/widgets/type_widgets/file/Video.css @@ -27,10 +27,10 @@ flex: 1; align-items: center; gap: 0.5em; + display: flex; } .center { - display: flex; justify-content: center; } @@ -73,4 +73,24 @@ width: 80px; cursor: pointer; } + + .speed-dropdown { + position: relative; + + .tn-icon { + transform: translateY(-10%); + } + + .video-speed-label { + position: absolute; + bottom: 0; + left: 0; + right: 0; + transform: translateY(15%); + text-align: center; + color: white; + font-size: 0.6rem; + font-variant-numeric: tabular-nums; + } + } } diff --git a/apps/client/src/widgets/type_widgets/file/Video.tsx b/apps/client/src/widgets/type_widgets/file/Video.tsx index e158183dd5..bb6c48d9b7 100644 --- a/apps/client/src/widgets/type_widgets/file/Video.tsx +++ b/apps/client/src/widgets/type_widgets/file/Video.tsx @@ -6,6 +6,8 @@ import { useEffect, useRef, useState } from "preact/hooks"; import FNote from "../../../entities/fnote"; import { getUrlForDownload } from "../../../services/open"; import ActionButton from "../../react/ActionButton"; +import Dropdown from "../../react/Dropdown"; +import Icon from "../../react/Icon"; function formatTime(seconds: number): string { const mins = Math.floor(seconds / 60); @@ -49,7 +51,9 @@ export default function VideoPreview({ note }: { note: FNote }) {
-
+
+ +
}) ); } +const PLAYBACK_SPEEDS = [0.5, 1, 1.25, 1.5, 2]; + +function PlaybackSpeed({ videoRef }: { videoRef: RefObject }) { + const [speed, setSpeed] = useState(1); + + const selectSpeed = (rate: number) => { + const video = videoRef.current; + if (!video) return; + video.playbackRate = rate; + setSpeed(rate); + }; + + return ( + + + {speed}x + } + title="Playback speed" + > + {PLAYBACK_SPEEDS.map((rate) => ( +
  • + +
  • + ))} +
    + ); +} + function FullscreenButton({ targetRef }: { targetRef: RefObject }) { const [isFullscreen, setIsFullscreen] = useState(false);