From 2de6ae369e192000814e0f632d08134cbb5347bc Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 22 Jul 2026 00:10:03 +0300 Subject: [PATCH] fix: keep subtitles above player controls --- package.json | 2 +- pnpm-lock.yaml | 11 ++++++----- src/routes/Player/Player.js | 31 +++++++++++++++++++++++++++++++ src/routes/Player/useVideo.js | 13 +++++++++++-- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 3aebb9f4d..58971444e 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@stremio/stremio-colors": "5.2.0", "@stremio/stremio-core-web": "0.59.0", "@stremio/stremio-icons": "5.10.0", - "@stremio/stremio-video": "0.0.85", + "@stremio/stremio-video": "github:Stremio/stremio-video#583658c0a75171bff6218793133726f1380da677", "a-color-picker": "1.2.1", "bowser": "2.14.1", "buffer": "6.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7d7359f3d..d21b9a935 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: 5.10.0 version: 5.10.0 '@stremio/stremio-video': - specifier: 0.0.85 - version: 0.0.85 + specifier: github:Stremio/stremio-video#583658c0a75171bff6218793133726f1380da677 + version: https://codeload.github.com/Stremio/stremio-video/tar.gz/583658c0a75171bff6218793133726f1380da677 a-color-picker: specifier: 1.2.1 version: 1.2.1 @@ -1423,8 +1423,9 @@ packages: '@stremio/stremio-icons@5.10.0': resolution: {integrity: sha512-Zw/vGC3D2yeQfk8xv/tfMJTDvbCPOI91tBg4XpR2+EgbZSX8Xvm7Vz457PIhFPhTAwdOPHp0VX0M3gzjbt0zOg==} - '@stremio/stremio-video@0.0.85': - resolution: {integrity: sha512-andur3mBXo0oAc2xoB33HSw3ZUCXU83eeq9vQBazSKUY7QZxWwKQZ+Q+NiFpRKjD662imv4b0wU85xHbrLgJ1w==} + '@stremio/stremio-video@https://codeload.github.com/Stremio/stremio-video/tar.gz/583658c0a75171bff6218793133726f1380da677': + resolution: {gitHosted: true, integrity: sha512-P1RuSOYYHhesj1DLUYbx64y6pcIJH/RxI7voA1W5aj9YZIvzfYTgHSlRsUBQhr6qeSbQ4VlfgZVk4XbWKWe2Qg==, tarball: https://codeload.github.com/Stremio/stremio-video/tar.gz/583658c0a75171bff6218793133726f1380da677} + version: 0.0.85 '@stylistic/eslint-plugin-jsx@4.4.1': resolution: {integrity: sha512-83SInq4u7z71vWwGG+6ViOtlOmZ6tSrDkMPhrvdBBTGMLA0gs22WSdhQ4vZP3oJ5Xg4ythvqeUiFSedvVxzhyA==} @@ -6488,7 +6489,7 @@ snapshots: '@stremio/stremio-icons@5.10.0': {} - '@stremio/stremio-video@0.0.85': + '@stremio/stremio-video@https://codeload.github.com/Stremio/stremio-video/tar.gz/583658c0a75171bff6218793133726f1380da677': dependencies: buffer: 6.0.3 color: 4.2.3 diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 978ce1c3e..aaa60d1c8 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -288,6 +288,37 @@ const Player = () => { return keyboardSeekTime === null && immersed && !casting && video.state.paused !== null && !video.state.paused && !menusOpen; }, [keyboardSeekTime, immersed, casting, video.state.paused, menusOpen]); + React.useEffect(() => { + if (!video.state.manifest?.props.includes('subtitlesOffsetAdjustment')) { + return; + } + + const videoContainerElement = video.containerRef.current; + const controlBarElement = controlBarRef.current; + if (!videoContainerElement || !controlBarElement) { + return; + } + + const updateSubtitlesOffsetAdjustment = () => { + const videoHeight = videoContainerElement.getBoundingClientRect().height; + const controlBarHeight = overlayHidden ? 0 : controlBarElement.getBoundingClientRect().height; + const offsetAdjustment = videoHeight > 0 ? Math.ceil(controlBarHeight / videoHeight * 100) : 0; + video.setSubtitlesOffsetAdjustment(offsetAdjustment); + }; + + updateSubtitlesOffsetAdjustment(); + + if (typeof ResizeObserver === 'undefined') { + window.addEventListener('resize', updateSubtitlesOffsetAdjustment); + return () => window.removeEventListener('resize', updateSubtitlesOffsetAdjustment); + } + + const resizeObserver = new ResizeObserver(updateSubtitlesOffsetAdjustment); + resizeObserver.observe(videoContainerElement); + resizeObserver.observe(controlBarElement); + return () => resizeObserver.disconnect(); + }, [overlayHidden, video.state.manifest, video.setSubtitlesOffsetAdjustment]); + const onPlaybackSpeedChanged = React.useCallback((rate, skipUpdate) => { video.setPlaybackSpeed(rate); diff --git a/src/routes/Player/useVideo.js b/src/routes/Player/useVideo.js index 570888ff1..d733bc936 100644 --- a/src/routes/Player/useVideo.js +++ b/src/routes/Player/useVideo.js @@ -43,7 +43,7 @@ const useVideo = () => { fullscreen: null, }); - const dispatch = (action, options) => { + const dispatch = React.useCallback((action, options) => { if (video.current && containerRef.current) { try { video.current.dispatch(action, { @@ -54,7 +54,7 @@ const useVideo = () => { console.error('Video:', error); } } - }; + }, []); const load = (args, options) => { dispatch({ @@ -144,6 +144,14 @@ const useVideo = () => { setProp('extraSubtitlesOffset', offset); }; + const setSubtitlesOffsetAdjustment = React.useCallback((offset) => { + dispatch({ + type: 'setProp', + propName: 'subtitlesOffsetAdjustment', + propValue: offset, + }); + }, [dispatch]); + const setVideoScale = (scale) => { setProp('videoScale', scale); }; @@ -244,6 +252,7 @@ const useVideo = () => { setSubtitlesDelay, setSubtitlesSize, setSubtitlesOffset, + setSubtitlesOffsetAdjustment, setSubtitlesTextColor, setSubtitlesBackgroundColor, setSubtitlesOutlineColor,