From 3df8eb65d020940623b00cbfa94134dd9adb21e3 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 8 Jan 2025 20:41:55 +0100 Subject: [PATCH 01/32] feat: allow to drop local subtitles --- src/common/CONSTANTS.js | 6 ++++ src/common/index.js | 2 ++ src/common/onFileDrop.ts | 31 +++++++++++++++++++ src/routes/Player/Player.js | 12 +++++-- .../Player/SubtitlesMenu/SubtitlesMenu.js | 12 +++++-- src/routes/Player/useVideo.js | 12 +++++++ src/services/DragAndDrop/DragAndDrop.js | 4 +++ 7 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 src/common/onFileDrop.ts diff --git a/src/common/CONSTANTS.js b/src/common/CONSTANTS.js index 727c152fa..ea88b0114 100644 --- a/src/common/CONSTANTS.js +++ b/src/common/CONSTANTS.js @@ -41,6 +41,11 @@ const ICON_FOR_TYPE = new Map([ ['other', 'movies'], ]); +const SUPPORTED_LOCAL_SUBTITLES = [ + 'application/x-subrip', + 'text/vtt', +]; + const EXTERNAL_PLAYERS = [ { label: 'EXTERNAL_PLAYER_DISABLED', @@ -113,6 +118,7 @@ module.exports = { WRITERS_LINK_CATEGORY, TYPE_PRIORITIES, ICON_FOR_TYPE, + SUPPORTED_LOCAL_SUBTITLES, EXTERNAL_PLAYERS, WHITELISTED_HOSTS, }; diff --git a/src/common/index.js b/src/common/index.js index 4c514dfbe..2dba2ad54 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -13,6 +13,7 @@ const languages = require('./languages'); const routesRegexp = require('./routesRegexp'); const useAnimationFrame = require('./useAnimationFrame'); const useBinaryState = require('./useBinaryState'); +const { default: onFileDrop } = require('./onFileDrop'); const useFullscreen = require('./useFullscreen'); const useLiveRef = require('./useLiveRef'); const useModelState = require('./useModelState'); @@ -41,6 +42,7 @@ module.exports = { routesRegexp, useAnimationFrame, useBinaryState, + onFileDrop, useFullscreen, useLiveRef, useModelState, diff --git a/src/common/onFileDrop.ts b/src/common/onFileDrop.ts new file mode 100644 index 000000000..0060a975a --- /dev/null +++ b/src/common/onFileDrop.ts @@ -0,0 +1,31 @@ +import { useEffect } from 'react'; + +const onFileDrop = (types: string[], callback: (file: File) => void) => { + const onDragOver = (event: DragEvent) => { + event.preventDefault(); + }; + + const onDrop = (event: DragEvent) => { + event.preventDefault(); + + if (event.dataTransfer && event.dataTransfer.files.length > 0) { + const file = event.dataTransfer.files[0]; + + if (types.includes(file.type)) { + callback(file); + } + } + }; + + useEffect(() => { + window.addEventListener('dragover', onDragOver); + window.addEventListener('drop', onDrop); + + return () => { + window.removeEventListener('dragover', onDragOver); + window.removeEventListener('drop', onDrop); + }; + }, []); +}; + +export default onFileDrop; diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index c76a8dcae..86867d3c0 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -8,7 +8,7 @@ const langs = require('langs'); const { useTranslation } = require('react-i18next'); const { useRouteFocused } = require('stremio-router'); const { useServices } = require('stremio/services'); -const { useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender } = require('stremio/common'); +const { onFileDrop, useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender, CONSTANTS } = require('stremio/common'); const { HorizontalNavBar, Transition } = require('stremio/components'); const BufferingLoader = require('./BufferingLoader'); const VolumeChangeIndicator = require('./VolumeChangeIndicator'); @@ -133,7 +133,10 @@ const Player = ({ urlParams, queryParams }) => { toast.show({ type: 'success', title: t('PLAYER_SUBTITLES_LOADED'), - message: track.exclusive ? t('PLAYER_SUBTITLES_LOADED_EXCLUSIVE') : t('PLAYER_SUBTITLES_LOADED_ORIGIN', { origin: track.origin }), + message: + track.exclusive ? t('PLAYER_SUBTITLES_LOADED_EXCLUSIVE') : + track.local ? t('PLAYER_SUBTITLES_LOADED_LOCAL') : + t('PLAYER_SUBTITLES_LOADED_ORIGIN', { origin: track.origin }), timeout: 3000 }); }, []); @@ -270,6 +273,11 @@ const Player = ({ urlParams, queryParams }) => { event.nativeEvent.immersePrevented = true; }, []); + onFileDrop(CONSTANTS.SUPPORTED_LOCAL_SUBTITLES, async (file) => { + const buffer = await file.arrayBuffer(); + video.addLocalSubtitles(file.name, buffer); + }); + React.useEffect(() => { setError(null); video.unload(); diff --git a/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js b/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js index 44cd20864..72de44e0b 100644 --- a/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js +++ b/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js @@ -10,11 +10,13 @@ const styles = require('./styles'); const { t } = require('i18next'); const ORIGIN_PRIORITIES = { + 'LOCAL': 3, 'EMBEDDED': 2, - 'EXCLUSIVE': 1 + 'EXCLUSIVE': 1, }; const LANGUAGE_PRIORITIES = { - 'eng': 1 + 'local': 2, + 'eng': 1, }; const SubtitlesMenu = React.memo((props) => { @@ -161,7 +163,11 @@ const SubtitlesMenu = React.memo((props) => { {subtitlesLanguages.map((lang, index) => ( + + + + + + ); +}; + +export default UpdaterBanner; diff --git a/src/App/UpdaterBanner/index.ts b/src/App/UpdaterBanner/index.ts new file mode 100644 index 000000000..e4306ecb2 --- /dev/null +++ b/src/App/UpdaterBanner/index.ts @@ -0,0 +1,2 @@ +import UpdaterBanner from './UpdaterBanner'; +export default UpdaterBanner; diff --git a/src/App/styles.less b/src/App/styles.less index a413ed163..e2eed685a 100644 --- a/src/App/styles.less +++ b/src/App/styles.less @@ -208,6 +208,14 @@ html { } } + .updater-banner-container { + z-index: 1; + position: absolute; + left: 0; + right: 0; + bottom: 0; + } + .router { width: 100%; height: 100%; diff --git a/src/common/animations.less b/src/common/animations.less index c7a30d2fb..91dbe386d 100644 --- a/src/common/animations.less +++ b/src/common/animations.less @@ -69,6 +69,19 @@ transform: translateX(100%); } +.slide-up-enter { + transform: translateY(100%); +} + +.slide-up-active { + transform: translateY(0%); + transition: transform 0.3s cubic-bezier(0.32, 0, 0.67, 0); +} + +.slide-up-exit { + transform: translateY(100%); +} + @keyframes fade-in-no-motion { 0% { opacity: 0; From e5882ea143359d53f5af44c07b98070eb4d23c88 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 30 Jan 2025 11:10:45 +0100 Subject: [PATCH 13/32] refactor(App): update updater banner style --- src/App/UpdaterBanner/UpdaterBanner.less | 49 ++++++++++++++---------- src/App/UpdaterBanner/UpdaterBanner.tsx | 16 ++++---- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/App/UpdaterBanner/UpdaterBanner.less b/src/App/UpdaterBanner/UpdaterBanner.less index 83956ef50..9928fb493 100644 --- a/src/App/UpdaterBanner/UpdaterBanner.less +++ b/src/App/UpdaterBanner/UpdaterBanner.less @@ -2,38 +2,45 @@ height: 4rem; display: flex; align-items: center; - justify-content: space-between; + justify-content: center; + gap: 1rem; padding: 0 1rem; font-size: 1rem; font-weight: bold; color: var(--primary-foreground-color); background-color: var(--primary-accent-color); - .buttons { + .button { display: flex; flex-direction: row; - gap: 0.75rem; + align-items: center; + justify-content: center; + height: 2.5rem; + padding: 0 1rem; + border-radius: var(--border-radius); + color: var(--primary-background-color); + background-color: var(--primary-foreground-color); + transition: all 0.1s ease-out; - .button { - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - height: 2.75rem; - padding: 0 1rem; - border-radius: var(--border-radius); - transition: all 0.1s ease-out; + &:hover { + color: var(--primary-foreground-color); + background-color: transparent; + box-shadow: inset 0 0 0 0.15rem var(--primary-foreground-color); + } + } - &.suggested { - color: var(--primary-background-color); - background-color: var(--primary-foreground-color); - } + .close { + position: absolute; + right: 0; + height: 4rem; + width: 4rem; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; - &:hover { - color: var(--primary-foreground-color); - background-color: transparent; - box-shadow: inset 0 0 0 0.15rem var(--primary-foreground-color); - } + .icon { + height: 2rem; } } } \ No newline at end of file diff --git a/src/App/UpdaterBanner/UpdaterBanner.tsx b/src/App/UpdaterBanner/UpdaterBanner.tsx index bf18077a8..a6b48066d 100644 --- a/src/App/UpdaterBanner/UpdaterBanner.tsx +++ b/src/App/UpdaterBanner/UpdaterBanner.tsx @@ -1,9 +1,9 @@ import React, { useEffect } from 'react'; +import Icon from '@stremio/stremio-icons/react'; import { useServices } from 'stremio/services'; import { useBinaryState } from 'stremio/common'; import { Button, Transition } from 'stremio/components'; import styles from './UpdaterBanner.less'; -import classNames from 'classnames'; type Props = { className: string, @@ -32,14 +32,12 @@ const UpdaterBanner = ({ className }: Props) => {
A new version of Stremio is available
-
- - -
+ + From 77e283d9344b5242b54d58fec2a70df50d918ec2 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 30 Jan 2025 14:57:37 +0100 Subject: [PATCH 14/32] refactor: use useShell hook for UpdaterBanner --- src/App/UpdaterBanner/UpdaterBanner.tsx | 9 +++++---- src/common/Platform/Platform.tsx | 2 +- src/common/index.js | 2 ++ src/common/{Platform => }/useShell.ts | 0 4 files changed, 8 insertions(+), 5 deletions(-) rename src/common/{Platform => }/useShell.ts (100%) diff --git a/src/App/UpdaterBanner/UpdaterBanner.tsx b/src/App/UpdaterBanner/UpdaterBanner.tsx index a6b48066d..cf80c198a 100644 --- a/src/App/UpdaterBanner/UpdaterBanner.tsx +++ b/src/App/UpdaterBanner/UpdaterBanner.tsx @@ -1,7 +1,7 @@ import React, { useEffect } from 'react'; import Icon from '@stremio/stremio-icons/react'; import { useServices } from 'stremio/services'; -import { useBinaryState } from 'stremio/common'; +import { useBinaryState, useShell } from 'stremio/common'; import { Button, Transition } from 'stremio/components'; import styles from './UpdaterBanner.less'; @@ -11,17 +11,18 @@ type Props = { const UpdaterBanner = ({ className }: Props) => { const { shell } = useServices(); + const shellTransport = useShell(); const [visible, show, hide] = useBinaryState(false); const onInstallClick = () => { - shell.transport && shell.transport.send('autoupdater-notif-clicked'); + shellTransport.send('autoupdater-notif-clicked'); }; useEffect(() => { - shell.on('autoupdater-show-notif', show); + shell.transport && shell.transport.on('autoupdater-show-notif', show); return () => { - shell.off('autoupdater-show-notif', show); + shell.transport && shell.transport.off('autoupdater-show-notif', show); }; }); diff --git a/src/common/Platform/Platform.tsx b/src/common/Platform/Platform.tsx index 41e74b24f..375fe5e18 100644 --- a/src/common/Platform/Platform.tsx +++ b/src/common/Platform/Platform.tsx @@ -1,6 +1,6 @@ import React, { createContext, useContext } from 'react'; import { WHITELISTED_HOSTS } from 'stremio/common/CONSTANTS'; -import useShell from './useShell'; +import { useShell } from 'stremio/common'; import { name, isMobile } from './device'; interface PlatformContext { diff --git a/src/common/index.js b/src/common/index.js index 4c514dfbe..61d2a3933 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -19,6 +19,7 @@ const useModelState = require('./useModelState'); const useNotifications = require('./useNotifications'); const useOnScrollToBottom = require('./useOnScrollToBottom'); const useProfile = require('./useProfile'); +const { default: useShell } = require('./useShell'); const useStreamingServer = require('./useStreamingServer'); const useTorrent = require('./useTorrent'); const useTranslate = require('./useTranslate'); @@ -47,6 +48,7 @@ module.exports = { useNotifications, useOnScrollToBottom, useProfile, + useShell, useStreamingServer, useTorrent, useTranslate, diff --git a/src/common/Platform/useShell.ts b/src/common/useShell.ts similarity index 100% rename from src/common/Platform/useShell.ts rename to src/common/useShell.ts From e2b9114ecef90c5ae561f2163272c4b94fdcec71 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 30 Jan 2025 17:01:28 +0100 Subject: [PATCH 15/32] fix(Platform): import issue --- src/common/Platform/Platform.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/Platform/Platform.tsx b/src/common/Platform/Platform.tsx index 375fe5e18..2212303e4 100644 --- a/src/common/Platform/Platform.tsx +++ b/src/common/Platform/Platform.tsx @@ -1,6 +1,6 @@ import React, { createContext, useContext } from 'react'; import { WHITELISTED_HOSTS } from 'stremio/common/CONSTANTS'; -import { useShell } from 'stremio/common'; +import useShell from 'stremio/common/useShell'; import { name, isMobile } from './device'; interface PlatformContext { From a95f07f19d3652ce18eea8ffaa1c98bed53cc1f7 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 30 Jan 2025 17:02:24 +0100 Subject: [PATCH 16/32] fix(UpdateBanner): missing useEffect deps array --- src/App/UpdaterBanner/UpdaterBanner.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App/UpdaterBanner/UpdaterBanner.tsx b/src/App/UpdaterBanner/UpdaterBanner.tsx index cf80c198a..b3135a6c3 100644 --- a/src/App/UpdaterBanner/UpdaterBanner.tsx +++ b/src/App/UpdaterBanner/UpdaterBanner.tsx @@ -24,7 +24,7 @@ const UpdaterBanner = ({ className }: Props) => { return () => { shell.transport && shell.transport.off('autoupdater-show-notif', show); }; - }); + }, []); return (
From 74682ddb6f279e599ac82a9f79a0011d694b3a7d Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 31 Jan 2025 10:02:06 +0100 Subject: [PATCH 17/32] build: typo in HtmlWebPackPlugin imagesPath --- webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index 751c5cbb6..36f6b6e50 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -244,7 +244,7 @@ module.exports = (env, argv) => ({ inject: false, scriptLoading: 'blocking', faviconsPath: 'favicons', - imagesPath: '$images', + imagesPath: 'images', }), new WebpackPwaManifest({ name: 'Stremio Web', From 05486a35bf41b74318344cf791ded0264dd6a1db Mon Sep 17 00:00:00 2001 From: Ivelin Megdanov Date: Tue, 4 Feb 2025 16:05:12 +0200 Subject: [PATCH 18/32] Add preview for truncated stream names --- .../MetaDetails/StreamsList/Stream/Stream.js | 5 +++++ .../StreamsList/Stream/styles.less | 22 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/routes/MetaDetails/StreamsList/Stream/Stream.js b/src/routes/MetaDetails/StreamsList/Stream/Stream.js index 768b8d40a..41f81b386 100644 --- a/src/routes/MetaDetails/StreamsList/Stream/Stream.js +++ b/src/routes/MetaDetails/StreamsList/Stream/Stream.js @@ -181,12 +181,17 @@ const Stream = ({ className, videoId, videoReleased, addonName, name, descriptio const renderMenu = React.useMemo(() => function renderMenu() { return (
+
+ {description} +
{ streamLink && } diff --git a/src/routes/MetaDetails/StreamsList/Stream/styles.less b/src/routes/MetaDetails/StreamsList/Stream/styles.less index 0461c77ee..06720a879 100644 --- a/src/routes/MetaDetails/StreamsList/Stream/styles.less +++ b/src/routes/MetaDetails/StreamsList/Stream/styles.less @@ -111,12 +111,29 @@ background-color: var(--secondary-accent-color); } + .menu-icon { + flex: none; + width: 1.7rem; + height: 1.7rem; + margin-right: 1rem; + color: var(--color-placeholder); + } + .context-menu-container { max-width: calc(90% - 1.5rem); z-index: 2; .context-menu-content { --spatial-navigation-contain: contain; + + .context-menu-title { + font-size: 0.9rem; + padding: 1rem 1.5rem; + font-weight: 100; + border-bottom: 1px solid var(--color-placeholder); + color: var(--primary-foreground-color); + white-space: break-spaces; + } .context-menu-option-container { display: flex; @@ -131,8 +148,9 @@ .context-menu-option-label { font-size: 1rem; - font-weight: 500; - color:var(--primary-foreground-color); + font-weight: 300; + color: var(--primary-foreground-color); + text-transform: capitalize; } } } From d9da7d5ab788e06bf6e2db79f16f0c88ab477e6c Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 5 Feb 2025 15:00:06 +0100 Subject: [PATCH 19/32] feat: support hardware decoding --- src/routes/Player/Player.js | 3 ++- src/routes/Settings/Settings.js | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index c76a8dcae..d727d6811 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -296,6 +296,7 @@ const Player = ({ urlParams, queryParams }) => { 0, forceTranscoding: forceTranscoding || casting, maxAudioChannels: settings.surroundSound ? 32 : 2, + hardwareDecoding: settings.hardwareDecoding, streamingServerURL: streamingServer.baseUrl ? casting ? streamingServer.baseUrl @@ -303,7 +304,7 @@ const Player = ({ urlParams, queryParams }) => { streamingServer.selected.transportUrl : null, - seriesInfo: player.seriesInfo + seriesInfo: player.seriesInfo, }, { chromecastTransport: chromecast.active ? chromecast.transport : null, shellTransport: shell.active ? shell.transport : null, diff --git a/src/routes/Settings/Settings.js b/src/routes/Settings/Settings.js index 24eaaaf5d..6ad15163a 100644 --- a/src/routes/Settings/Settings.js +++ b/src/routes/Settings/Settings.js @@ -488,17 +488,19 @@ const Settings = () => { {...playInExternalPlayerSelect} />
-
-
-
{ t('SETTINGS_HWDEC') }
-
- -
+ { + shell.active && +
+
+
{ t('SETTINGS_HWDEC') }
+
+ +
+ }
{ t('SETTINGS_NAV_STREAMING') }
From a68f7ddd53dfe1777575c21ab2acea643813a8f6 Mon Sep 17 00:00:00 2001 From: Alexandru Branza Date: Wed, 5 Feb 2025 16:49:31 +0200 Subject: [PATCH 20/32] Bump stremio-video --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4477c0b4f..d0c7ad763 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@stremio/stremio-colors": "5.2.0", "@stremio/stremio-core-web": "0.48.5", "@stremio/stremio-icons": "5.4.1", - "@stremio/stremio-video": "0.0.48", + "@stremio/stremio-video": "0.0.52", "a-color-picker": "1.2.1", "bowser": "2.11.0", "buffer": "6.0.3", @@ -3409,9 +3409,9 @@ ] }, "node_modules/@stremio/stremio-video": { - "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@stremio/stremio-video/-/stremio-video-0.0.48.tgz", - "integrity": "sha512-6ALGXCZC4NPsfhPcrwFWQzvH6UMMRsgSkHetnOhv9WmZ5ubiyUdbBzj9atGiGuuQz8pRcze66ztrub+dsaQbpw==", + "version": "0.0.52", + "resolved": "https://registry.npmjs.org/@stremio/stremio-video/-/stremio-video-0.0.52.tgz", + "integrity": "sha512-OlHC8FIvYEyGXcNAM4W044Dqx6CmGb5BV3fDU361SyUjO9gKXXUWdL7LwmwHeWFeuy2sK1MEg4AT2JPptvJ0rg==", "license": "MIT", "dependencies": { "buffer": "6.0.3", diff --git a/package.json b/package.json index 9587f9530..e80305bc9 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@stremio/stremio-colors": "5.2.0", "@stremio/stremio-core-web": "0.48.5", "@stremio/stremio-icons": "5.4.1", - "@stremio/stremio-video": "0.0.48", + "@stremio/stremio-video": "0.0.52", "a-color-picker": "1.2.1", "bowser": "2.11.0", "buffer": "6.0.3", From 4081396ae086036457a84dcb55d3132554cf9626 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Thu, 6 Feb 2025 12:16:29 +0200 Subject: [PATCH 21/32] feat: Player - Volume slider - on muted show 0 volume Signed-off-by: Lachezar Lechev --- src/routes/Player/ControlBar/ControlBar.js | 1 + .../Player/ControlBar/VolumeSlider/VolumeSlider.js | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js index 0fa6de1a4..745e2bd49 100644 --- a/src/routes/Player/ControlBar/ControlBar.js +++ b/src/routes/Player/ControlBar/ControlBar.js @@ -138,6 +138,7 @@ const ControlBar = ({
diff --git a/src/routes/Player/ControlBar/VolumeSlider/VolumeSlider.js b/src/routes/Player/ControlBar/VolumeSlider/VolumeSlider.js index 420f4ba41..a65ebfe9c 100644 --- a/src/routes/Player/ControlBar/VolumeSlider/VolumeSlider.js +++ b/src/routes/Player/ControlBar/VolumeSlider/VolumeSlider.js @@ -8,7 +8,7 @@ const { useRouteFocused } = require('stremio-router'); const { Slider } = require('stremio/components'); const styles = require('./styles'); -const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => { +const VolumeSlider = ({ className, volume, onVolumeChangeRequested, muted }) => { const disabled = volume === null || isNaN(volume); const routeFocused = useRouteFocused(); const [slidingVolume, setSlidingVolume] = React.useState(null); @@ -45,7 +45,9 @@ const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => { className={classnames(className, styles['volume-slider'], { 'active': slidingVolume !== null })} value={ !disabled ? - slidingVolume !== null ? slidingVolume : volume + !muted ? + slidingVolume !== null ? slidingVolume : volume + : 0 : 100 } @@ -61,7 +63,8 @@ const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => { VolumeSlider.propTypes = { className: PropTypes.string, volume: PropTypes.number, - onVolumeChangeRequested: PropTypes.func + onVolumeChangeRequested: PropTypes.func, + muted: PropTypes.bool, }; module.exports = VolumeSlider; From 9d18a1bb61d969b05f4034565f7b64cdb747e847 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 6 Feb 2025 18:10:34 +0100 Subject: [PATCH 22/32] fix: drop srt file with shell --- src/common/CONSTANTS.js | 6 ++++++ src/common/FileDrop/FileDrop.tsx | 16 ++++++++++------ src/common/FileDrop/utils.ts | 19 +++++++++++++++++++ src/routes/Player/Player.js | 5 ++--- src/services/DragAndDrop/DragAndDrop.js | 2 ++ 5 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 src/common/FileDrop/utils.ts diff --git a/src/common/CONSTANTS.js b/src/common/CONSTANTS.js index ea88b0114..8e4e3efdc 100644 --- a/src/common/CONSTANTS.js +++ b/src/common/CONSTANTS.js @@ -41,6 +41,11 @@ const ICON_FOR_TYPE = new Map([ ['other', 'movies'], ]); +const MIME_SIGNATURES = { + 'application/x-subrip': ['310D0A', '310A'], + 'text/vtt': ['574542565454'], +}; + const SUPPORTED_LOCAL_SUBTITLES = [ 'application/x-subrip', 'text/vtt', @@ -118,6 +123,7 @@ module.exports = { WRITERS_LINK_CATEGORY, TYPE_PRIORITIES, ICON_FOR_TYPE, + MIME_SIGNATURES, SUPPORTED_LOCAL_SUBTITLES, EXTERNAL_PLAYERS, WHITELISTED_HOSTS, diff --git a/src/common/FileDrop/FileDrop.tsx b/src/common/FileDrop/FileDrop.tsx index 9117a4c7a..aae4e146b 100644 --- a/src/common/FileDrop/FileDrop.tsx +++ b/src/common/FileDrop/FileDrop.tsx @@ -1,8 +1,9 @@ import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'; import classNames from 'classnames'; +import { isFileType } from './utils'; export type FileType = string; -export type FileDropListener = (file: File) => void; +export type FileDropListener = (filename: string, buffer: ArrayBuffer) => void; type FileDropContext = { on: (type: FileType, listener: FileDropListener) => void, @@ -31,15 +32,18 @@ const FileDropProvider = ({ className, children }: Props) => { const onDrop = useCallback((event: DragEvent) => { event.preventDefault(); - const { dataTransfer } = event; - if (dataTransfer && dataTransfer.files.length > 0) { + if (dataTransfer && dataTransfer?.files.length > 0) { const file = dataTransfer.files[0]; - listeners - .filter(([type]) => type === file.type) - .forEach(([, listerner]) => listerner(file)); + file + .arrayBuffer() + .then((buffer) => { + listeners + .filter(([type]) => file.type ? type === file.type : isFileType(buffer, type)) + .forEach(([, listerner]) => listerner(file.name, buffer)); + }); } setActive(false); diff --git a/src/common/FileDrop/utils.ts b/src/common/FileDrop/utils.ts new file mode 100644 index 000000000..b5427ecfb --- /dev/null +++ b/src/common/FileDrop/utils.ts @@ -0,0 +1,19 @@ +import { MIME_SIGNATURES } from 'stremio/common/CONSTANTS'; + +const SIGNATURES = MIME_SIGNATURES as Record; + +const isFileType = (buffer: ArrayBuffer, type: string) => { + const signatures = SIGNATURES[type]; + + return signatures.some((signature) => { + const array = new Uint8Array(buffer); + const signatureBuffer = Buffer.from(signature, 'hex'); + const bufferToCompare = array.subarray(0, signatureBuffer.length); + + return Buffer.compare(signatureBuffer, bufferToCompare) === 0; + }); +}; + +export { + isFileType, +}; \ No newline at end of file diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 5ea8975f0..4dbc12295 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -277,9 +277,8 @@ const Player = ({ urlParams, queryParams }) => { event.nativeEvent.immersePrevented = true; }, []); - onFileDrop(CONSTANTS.SUPPORTED_LOCAL_SUBTITLES, async (file) => { - const buffer = await file.arrayBuffer(); - video.addLocalSubtitles(file.name, buffer); + onFileDrop(CONSTANTS.SUPPORTED_LOCAL_SUBTITLES, async (filename, buffer) => { + video.addLocalSubtitles(filename, buffer); }); React.useEffect(() => { diff --git a/src/services/DragAndDrop/DragAndDrop.js b/src/services/DragAndDrop/DragAndDrop.js index 6e20a840e..1538c328e 100644 --- a/src/services/DragAndDrop/DragAndDrop.js +++ b/src/services/DragAndDrop/DragAndDrop.js @@ -40,6 +40,8 @@ function DragAndDrop({ core }) { break; case 'text/vtt': break; + case '': + break; default: { events.emit('error', { message: 'Unsupported file', From 330fac3f3987d484a04d1eab5e63844fc7ff4d63 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 6 Feb 2025 18:29:15 +0100 Subject: [PATCH 23/32] style: lint --- src/common/FileDrop/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/FileDrop/utils.ts b/src/common/FileDrop/utils.ts index b5427ecfb..f9996aed3 100644 --- a/src/common/FileDrop/utils.ts +++ b/src/common/FileDrop/utils.ts @@ -16,4 +16,4 @@ const isFileType = (buffer: ArrayBuffer, type: string) => { export { isFileType, -}; \ No newline at end of file +}; From 617b0e3125f7cf199d5ab96d8466cc1e84cdd896 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 7 Feb 2025 11:28:51 +0100 Subject: [PATCH 24/32] chore: update stremio-video and stremio-translations --- package-lock.json | 14 +++++++------- package.json | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index be53e9ec7..994e15d3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@stremio/stremio-colors": "5.2.0", "@stremio/stremio-core-web": "0.48.4", "@stremio/stremio-icons": "5.4.1", - "@stremio/stremio-video": "0.0.48", + "@stremio/stremio-video": "github:Stremio/stremio-video#436fe5a988ab0953a61aa043666cae1dd9522882", "a-color-picker": "1.2.1", "bowser": "2.11.0", "buffer": "6.0.3", @@ -36,7 +36,7 @@ "react-i18next": "^15.1.3", "react-is": "18.3.1", "spatial-navigation-polyfill": "github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6", - "stremio-translations": "github:Stremio/stremio-translations#a0f50634202f748a57907b645d2cd92fbaa479dd", + "stremio-translations": "github:Stremio/stremio-translations#f7d327d822f1061947568042bfb3dffde5525a30", "url": "0.11.4", "use-long-press": "^3.2.0" }, @@ -3409,9 +3409,9 @@ ] }, "node_modules/@stremio/stremio-video": { - "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@stremio/stremio-video/-/stremio-video-0.0.48.tgz", - "integrity": "sha512-6ALGXCZC4NPsfhPcrwFWQzvH6UMMRsgSkHetnOhv9WmZ5ubiyUdbBzj9atGiGuuQz8pRcze66ztrub+dsaQbpw==", + "version": "0.0.50", + "resolved": "git+ssh://git@github.com/Stremio/stremio-video.git#436fe5a988ab0953a61aa043666cae1dd9522882", + "integrity": "sha512-yKVKGl+qHTki2wAhJEauql2nKFDuX8bZXX5SrWLyNTI9cw/86UbQd7TEqvS2d9cBTMj9UrxQxMAG6zrKaSmwxg==", "license": "MIT", "dependencies": { "buffer": "6.0.3", @@ -13374,8 +13374,8 @@ }, "node_modules/stremio-translations": { "version": "1.44.9", - "resolved": "git+ssh://git@github.com/Stremio/stremio-translations.git#a0f50634202f748a57907b645d2cd92fbaa479dd", - "integrity": "sha512-JJpd1JJet3T6/VTNdZ2NZ7uvHJ4zkuyqo5BnTcDGqLVNO/OpicGqKhZjE4WGSgmuhsfPBU8T0ICCfzKu2xpvKg==", + "resolved": "git+ssh://git@github.com/Stremio/stremio-translations.git#f7d327d822f1061947568042bfb3dffde5525a30", + "integrity": "sha512-kqOI4fjs0yaG/LuEgR7IobDfi5GFZkjaYzEvHS+Cb822sE/BECHIRFVNWy05j4TNtwK60kSQX0KPrILRwKXD/Q==", "license": "MIT" }, "node_modules/string_decoder": { diff --git a/package.json b/package.json index 79593f9d5..1c061061b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@stremio/stremio-colors": "5.2.0", "@stremio/stremio-core-web": "0.48.4", "@stremio/stremio-icons": "5.4.1", - "@stremio/stremio-video": "0.0.48", + "@stremio/stremio-video": "github:Stremio/stremio-video#436fe5a988ab0953a61aa043666cae1dd9522882", "a-color-picker": "1.2.1", "bowser": "2.11.0", "buffer": "6.0.3", @@ -40,7 +40,7 @@ "react-i18next": "^15.1.3", "react-is": "18.3.1", "spatial-navigation-polyfill": "github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6", - "stremio-translations": "github:Stremio/stremio-translations#a0f50634202f748a57907b645d2cd92fbaa479dd", + "stremio-translations": "github:Stremio/stremio-translations#f7d327d822f1061947568042bfb3dffde5525a30", "url": "0.11.4", "use-long-press": "^3.2.0" }, From e2b2286c98739fde26d5b17ce8b811d4783cb311 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 7 Feb 2025 11:32:31 +0100 Subject: [PATCH 25/32] chore: update stremio-video --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4477c0b4f..14e5f5e38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@stremio/stremio-colors": "5.2.0", "@stremio/stremio-core-web": "0.48.5", "@stremio/stremio-icons": "5.4.1", - "@stremio/stremio-video": "0.0.48", + "@stremio/stremio-video": "github:Stremio/stremio-video#b5e6eb7c3aa85703c3468c53e489d7ec47daccae", "a-color-picker": "1.2.1", "bowser": "2.11.0", "buffer": "6.0.3", @@ -3409,9 +3409,9 @@ ] }, "node_modules/@stremio/stremio-video": { - "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@stremio/stremio-video/-/stremio-video-0.0.48.tgz", - "integrity": "sha512-6ALGXCZC4NPsfhPcrwFWQzvH6UMMRsgSkHetnOhv9WmZ5ubiyUdbBzj9atGiGuuQz8pRcze66ztrub+dsaQbpw==", + "version": "0.0.52", + "resolved": "git+ssh://git@github.com/Stremio/stremio-video.git#b5e6eb7c3aa85703c3468c53e489d7ec47daccae", + "integrity": "sha512-ywXVR/blyHdP/8q458+sL7cfvPj5RyE6esuxZBU6qejKxX+U62x6qcky1dNL5ZWub5YYucbqfjftaVuuNz+dug==", "license": "MIT", "dependencies": { "buffer": "6.0.3", diff --git a/package.json b/package.json index 9587f9530..c6eda5722 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@stremio/stremio-colors": "5.2.0", "@stremio/stremio-core-web": "0.48.5", "@stremio/stremio-icons": "5.4.1", - "@stremio/stremio-video": "0.0.48", + "@stremio/stremio-video": "github:Stremio/stremio-video#b5e6eb7c3aa85703c3468c53e489d7ec47daccae", "a-color-picker": "1.2.1", "bowser": "2.11.0", "buffer": "6.0.3", From 6605eafd7896307d38cce74a5383a10d69470874 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 7 Feb 2025 12:04:40 +0100 Subject: [PATCH 26/32] chore: update stremio-translations --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4477c0b4f..7317cea49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "react-i18next": "^15.1.3", "react-is": "18.3.1", "spatial-navigation-polyfill": "github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6", - "stremio-translations": "github:Stremio/stremio-translations#a0f50634202f748a57907b645d2cd92fbaa479dd", + "stremio-translations": "github:Stremio/stremio-translations#afda3a5a52e3b91b39ed6e61a2849d8e6887641f", "url": "0.11.4", "use-long-press": "^3.2.0" }, @@ -13374,8 +13374,8 @@ }, "node_modules/stremio-translations": { "version": "1.44.9", - "resolved": "git+ssh://git@github.com/Stremio/stremio-translations.git#a0f50634202f748a57907b645d2cd92fbaa479dd", - "integrity": "sha512-JJpd1JJet3T6/VTNdZ2NZ7uvHJ4zkuyqo5BnTcDGqLVNO/OpicGqKhZjE4WGSgmuhsfPBU8T0ICCfzKu2xpvKg==", + "resolved": "git+ssh://git@github.com/Stremio/stremio-translations.git#afda3a5a52e3b91b39ed6e61a2849d8e6887641f", + "integrity": "sha512-uAWlQsiObblYeLUf/cATCecqNS3Md34pGgeCcH2HBjZI6drSD6DEVYHd4Sxjmv+vmjnngQyHWr6ThHP27mWc4Q==", "license": "MIT" }, "node_modules/string_decoder": { diff --git a/package.json b/package.json index 9587f9530..001eec76c 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "react-i18next": "^15.1.3", "react-is": "18.3.1", "spatial-navigation-polyfill": "github:Stremio/spatial-navigation#64871b1422466f5f45d24ebc8bbd315b2ebab6a6", - "stremio-translations": "github:Stremio/stremio-translations#a0f50634202f748a57907b645d2cd92fbaa479dd", + "stremio-translations": "github:Stremio/stremio-translations#afda3a5a52e3b91b39ed6e61a2849d8e6887641f", "url": "0.11.4", "use-long-press": "^3.2.0" }, From 6ba966d306e3d9c1471ca12ed7bb5a181af9758b Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 7 Feb 2025 12:05:31 +0100 Subject: [PATCH 27/32] refactor(UpdaterBanner): add translation strings --- src/App/UpdaterBanner/UpdaterBanner.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/App/UpdaterBanner/UpdaterBanner.tsx b/src/App/UpdaterBanner/UpdaterBanner.tsx index cf80c198a..3c1a16ab9 100644 --- a/src/App/UpdaterBanner/UpdaterBanner.tsx +++ b/src/App/UpdaterBanner/UpdaterBanner.tsx @@ -1,5 +1,6 @@ import React, { useEffect } from 'react'; import Icon from '@stremio/stremio-icons/react'; +import { useTranslation } from 'react-i18next'; import { useServices } from 'stremio/services'; import { useBinaryState, useShell } from 'stremio/common'; import { Button, Transition } from 'stremio/components'; @@ -10,6 +11,7 @@ type Props = { }; const UpdaterBanner = ({ className }: Props) => { + const { t } = useTranslation(); const { shell } = useServices(); const shellTransport = useShell(); const [visible, show, hide] = useBinaryState(false); @@ -31,10 +33,10 @@ const UpdaterBanner = ({ className }: Props) => {
- A new version of Stremio is available + { t('UPDATER_TITLE') }