From 6e00a3384cdaebb406ab24a5dbfd2e8302fa0310 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 22 Jan 2025 18:39:45 +0100 Subject: [PATCH 1/3] feat: add mark season as watched for videos --- src/components/Video/Video.js | 16 ++++++++++++++-- .../MetaDetails/VideosList/VideosList.js | 18 ++++++++++++++++++ src/routes/Player/SideDrawer/SideDrawer.tsx | 17 +++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/components/Video/Video.js b/src/components/Video/Video.js index efa1a6847..0bcb569a5 100644 --- a/src/components/Video/Video.js +++ b/src/components/Video/Video.js @@ -11,7 +11,7 @@ const useBinaryState = require('stremio/common/useBinaryState'); const VideoPlaceholder = require('./VideoPlaceholder'); const styles = require('./styles'); -const Video = ({ className, id, title, thumbnail, episode, released, upcoming, watched, progress, scheduled, deepLinks, onMarkVideoAsWatched, ...props }) => { +const Video = ({ className, id, title, thumbnail, season, episode, released, upcoming, watched, progress, scheduled, seasonWatched, deepLinks, onMarkVideoAsWatched, onMarkSeasonAsWatched, ...props }) => { const routeFocused = useRouteFocused(); const [menuOpen, , closeMenu, toggleMenu] = useBinaryState(false); const popupLabelOnMouseUp = React.useCallback((event) => { @@ -50,6 +50,12 @@ const Video = ({ className, id, title, thumbnail, episode, released, upcoming, w closeMenu(); onMarkVideoAsWatched({ id, released }, watched); }, [id, released, watched]); + const toggleWatchedSeasonOnClick = React.useCallback((event) => { + event.preventDefault(); + event.stopPropagation(); + closeMenu(); + onMarkSeasonAsWatched(season, seasonWatched); + }, [season, seasonWatched, onMarkSeasonAsWatched]); const videoButtonOnClick = React.useCallback(() => { if (deepLinks) { if (typeof deepLinks.player === 'string') { @@ -142,9 +148,12 @@ const Video = ({ className, id, title, thumbnail, episode, released, upcoming, w + ); - }, [watched, toggleWatchedOnClick]); + }, [watched, seasonWatched, toggleWatchedOnClick]); React.useEffect(() => { if (!routeFocused) { closeMenu(); @@ -182,17 +191,20 @@ Video.propTypes = { id: PropTypes.string, title: PropTypes.string, thumbnail: PropTypes.string, + season: PropTypes.number, episode: PropTypes.number, released: PropTypes.instanceOf(Date), upcoming: PropTypes.bool, watched: PropTypes.bool, progress: PropTypes.number, scheduled: PropTypes.bool, + seasonWatched: PropTypes.bool, deepLinks: PropTypes.shape({ metaDetailsStreams: PropTypes.string, player: PropTypes.string }), onMarkVideoAsWatched: PropTypes.func, + onMarkSeasonAsWatched: PropTypes.func, }; module.exports = Video; diff --git a/src/routes/MetaDetails/VideosList/VideosList.js b/src/routes/MetaDetails/VideosList/VideosList.js index 999a1a1ae..557b3df1f 100644 --- a/src/routes/MetaDetails/VideosList/VideosList.js +++ b/src/routes/MetaDetails/VideosList/VideosList.js @@ -56,6 +56,11 @@ const VideosList = ({ className, metaItem, libraryItem, season, seasonOnSelect, return a.episode - b.episode; }); }, [videos, selectedSeason]); + + const seasonWatched = React.useMemo(() => { + return videosForSeason.every((video) => video.watched); + }, [videosForSeason]); + const [search, setSearch] = React.useState(''); const searchInputOnChange = React.useCallback((event) => { setSearch(event.currentTarget.value); @@ -71,6 +76,16 @@ const VideosList = ({ className, metaItem, libraryItem, season, seasonOnSelect, }); }; + const onMarkSeasonAsWatched = (season, watched) => { + core.transport.dispatch({ + action: 'MetaDetails', + args: { + action: 'MarkSeasonAsWatched', + args: [season, !watched] + } + }); + }; + return (
{ @@ -135,6 +150,7 @@ const VideosList = ({ className, metaItem, libraryItem, season, seasonOnSelect, id={video.id} title={video.title} thumbnail={video.thumbnail} + season={video.season} episode={video.episode} released={video.released} upcoming={video.upcoming} @@ -142,7 +158,9 @@ const VideosList = ({ className, metaItem, libraryItem, season, seasonOnSelect, progress={video.progress} deepLinks={video.deepLinks} scheduled={video.scheduled} + seasonWatched={seasonWatched} onMarkVideoAsWatched={onMarkVideoAsWatched} + onMarkSeasonAsWatched={onMarkSeasonAsWatched} /> )) } diff --git a/src/routes/Player/SideDrawer/SideDrawer.tsx b/src/routes/Player/SideDrawer/SideDrawer.tsx index 9ed713879..332ead719 100644 --- a/src/routes/Player/SideDrawer/SideDrawer.tsx +++ b/src/routes/Player/SideDrawer/SideDrawer.tsx @@ -47,6 +47,10 @@ const SideDrawer = memo(forwardRef(({ seriesInfo, classNa setSeason(parseInt(event.value)); }, []); + const seasonWatched = React.useMemo(() => { + return videos.every((video) => video.watched); + }, [videos]); + const onMarkVideoAsWatched = useCallback((video: Video, watched: boolean) => { core.transport.dispatch({ action: 'Player', @@ -57,6 +61,16 @@ const SideDrawer = memo(forwardRef(({ seriesInfo, classNa }); }, []); + const onMarkSeasonAsWatched = (season: number, watched: boolean) => { + core.transport.dispatch({ + action: 'MetaDetails', + args: { + action: 'MarkSeasonAsWatched', + args: [season, !watched] + } + }); + }; + const onMouseDown = (event: React.MouseEvent) => { event.stopPropagation(); }; @@ -95,14 +109,17 @@ const SideDrawer = memo(forwardRef(({ seriesInfo, classNa id={video.id} title={video.title} thumbnail={video.thumbnail} + season={video.season} episode={video.episode} released={video.released} upcoming={video.upcoming} watched={video.watched} + seasonWatched={seasonWatched} progress={video.progress} deepLinks={video.deepLinks} scheduled={video.scheduled} onMarkVideoAsWatched={onMarkVideoAsWatched} + onMarkSeasonAsWatched={onMarkSeasonAsWatched} /> ))}
From c08bed630d0a87cbf02f8e07a1b8c98474c01c9c Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 15 Feb 2025 07:27:24 +0100 Subject: [PATCH 2/3] fix(Player): use Player action for MarkSeasonAsWatched Co-authored-by: Timothy Z. --- src/routes/Player/SideDrawer/SideDrawer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/Player/SideDrawer/SideDrawer.tsx b/src/routes/Player/SideDrawer/SideDrawer.tsx index 332ead719..cb94e24e5 100644 --- a/src/routes/Player/SideDrawer/SideDrawer.tsx +++ b/src/routes/Player/SideDrawer/SideDrawer.tsx @@ -63,7 +63,7 @@ const SideDrawer = memo(forwardRef(({ seriesInfo, classNa const onMarkSeasonAsWatched = (season: number, watched: boolean) => { core.transport.dispatch({ - action: 'MetaDetails', + action: 'Player', args: { action: 'MarkSeasonAsWatched', args: [season, !watched] From 97832d42a8bb1ea4c50a04c3edbb359ba8cf3a20 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 21 Feb 2025 12:48:55 +0100 Subject: [PATCH 3/3] chore: update stremio-core-web --- 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 cd094aa9c..210c66388 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@babel/runtime": "7.26.0", "@sentry/browser": "8.42.0", "@stremio/stremio-colors": "5.2.0", - "@stremio/stremio-core-web": "0.48.5", + "@stremio/stremio-core-web": "0.49.0", "@stremio/stremio-icons": "5.4.1", "@stremio/stremio-video": "0.0.48", "a-color-picker": "1.2.1", @@ -3371,9 +3371,9 @@ "integrity": "sha512-dYlPgu9W/H7c9s1zmW5tiDnRenaUa4Hg1QCyOg1lhOcgSfM/bVTi5nnqX+IfvGTTUNA0zgzh8hI3o3miwnZxTg==" }, "node_modules/@stremio/stremio-core-web": { - "version": "0.48.5", - "resolved": "https://registry.npmjs.org/@stremio/stremio-core-web/-/stremio-core-web-0.48.5.tgz", - "integrity": "sha512-oDTNBrv8zZi1VGbeV+1Bm6CliI2rF23ERdJpz+gv8EnbFjRIo78WIsoS0yO0EOg8HHXYsFytPq5+c0+YlxmBlA==", + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@stremio/stremio-core-web/-/stremio-core-web-0.49.0.tgz", + "integrity": "sha512-oxJRVAE6z6Eh1B0qomdz6L2CVaTkwt70kDNC1TmHyGNo+Hhp2RaMlygqBKvBLXyHUXi82R67Mc11gT/JqlmaMw==", "license": "MIT", "dependencies": { "@babel/runtime": "7.24.1" diff --git a/package.json b/package.json index e777dd091..6339eab06 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@babel/runtime": "7.26.0", "@sentry/browser": "8.42.0", "@stremio/stremio-colors": "5.2.0", - "@stremio/stremio-core-web": "0.48.5", + "@stremio/stremio-core-web": "0.49.0", "@stremio/stremio-icons": "5.4.1", "@stremio/stremio-video": "0.0.48", "a-color-picker": "1.2.1",