From ff94c324b3db6ce8afb15c4038d19bffe6a28fed Mon Sep 17 00:00:00 2001 From: MerlinScheurer Date: Fri, 13 Jun 2025 20:10:57 +0200 Subject: [PATCH 01/10] Refac extract loading indicator into its own component --- frontend/src/components/InputConfig.tsx | 9 ++------- frontend/src/components/LoadingIndicator.tsx | 9 +++++++++ frontend/src/components/WatchedCheckBox.tsx | 5 ++--- frontend/src/pages/Login.tsx | 6 ++---- 4 files changed, 15 insertions(+), 14 deletions(-) create mode 100644 frontend/src/components/LoadingIndicator.tsx diff --git a/frontend/src/components/InputConfig.tsx b/frontend/src/components/InputConfig.tsx index a378a5fb..cf1bfa13 100644 --- a/frontend/src/components/InputConfig.tsx +++ b/frontend/src/components/InputConfig.tsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import LoadingIndicator from './LoadingIndicator'; type InputTextProps = { type: 'text' | 'number'; @@ -51,13 +52,7 @@ const InputConfig = ({ type, name, value, setValue, oldValue, updateCallback }: )} {oldValue !== null && } - {loading && ( - <> -
-
-
- - )} + {loading && } {success && }
diff --git a/frontend/src/components/LoadingIndicator.tsx b/frontend/src/components/LoadingIndicator.tsx new file mode 100644 index 00000000..0eaeaeb4 --- /dev/null +++ b/frontend/src/components/LoadingIndicator.tsx @@ -0,0 +1,9 @@ +const LoadingIndicator = () => { + return ( +
+
+
+ ); +}; + +export default LoadingIndicator; diff --git a/frontend/src/components/WatchedCheckBox.tsx b/frontend/src/components/WatchedCheckBox.tsx index 490bb3c3..0585ec1a 100644 --- a/frontend/src/components/WatchedCheckBox.tsx +++ b/frontend/src/components/WatchedCheckBox.tsx @@ -1,6 +1,7 @@ import iconUnseen from '/img/icon-unseen.svg'; import iconSeen from '/img/icon-seen.svg'; import { useEffect, useState } from 'react'; +import LoadingIndicator from './LoadingIndicator'; type WatchedCheckBoxProps = { watched: boolean; @@ -32,9 +33,7 @@ const WatchedCheckBox = ({ watched, onClick, onDone }: WatchedCheckBoxProps) => <> {loading && ( <> -
-
-
+ )} {!loading && watched && ( diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx index da8a0385..d07c392e 100644 --- a/frontend/src/pages/Login.tsx +++ b/frontend/src/pages/Login.tsx @@ -5,6 +5,7 @@ import Colours from '../configuration/colours/Colours'; import Button from '../components/Button'; import signIn from '../api/actions/signIn'; import loadAuth from '../api/loader/loadAuth'; +import LoadingIndicator from '../components/LoadingIndicator'; const Login = () => { const navigate = useNavigate(); @@ -134,10 +135,7 @@ const Login = () => { {waitingForBackend && ( <>

- Waiting for backend{' '} -

-
-
+ Waiting for backend

)} From bb4e5ecb503e22ae1633806899c4c4d93c5d550f Mon Sep 17 00:00:00 2001 From: Craig Alexander Date: Sun, 15 Jun 2025 05:19:14 -0400 Subject: [PATCH 02/10] Fix not found message showing as API is loading (#995) --- .gitignore | 2 + frontend/src/pages/ChannelVideo.tsx | 173 +++++++++++++--------------- 2 files changed, 85 insertions(+), 90 deletions(-) diff --git a/.gitignore b/.gitignore index 812a03ba..474bdc25 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ backend/.env # JavaScript stuff node_modules + +.editorconfig diff --git a/frontend/src/pages/ChannelVideo.tsx b/frontend/src/pages/ChannelVideo.tsx index e5a123c5..981c9aae 100644 --- a/frontend/src/pages/ChannelVideo.tsx +++ b/frontend/src/pages/ChannelVideo.tsx @@ -97,104 +97,97 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => { videoId, ]); - if (!channel) { - return ( -
-
-

Channel {channelId} not found!

-
- ); - } - return ( - <> - {`TA | Channel: ${channel.channel_name}`} - -
-
- -
- {videoAggs && ( - <> -

- {videoAggs.total_items.value} videos |{' '} - {videoAggs.total_duration.value_str} playback{' '} - | Total size{' '} - {humanFileSize(videoAggs.total_size.value, useSiUnits)} -

-
-
- - )} + setRefresh(true); + }} + /> +
+ + )} +
-
-
- -
- - - -
-
- {!hasVideos && ( - <> -

No videos found...

-

- Try going to the downloads page to start the scan - and download tasks. -

- - )} - - +
+
-
- {pagination && ( -
- + + + +
+
+ {!hasVideos && ( + <> +

No videos found...

+

+ Try going to the downloads page to start the + scan and download tasks. +

+ + )} + + +
- )} - + {pagination && ( +
+ +
+ )} + + ) ); }; From 990cb9aaecdc4c59628f09f1ddf5a347929f75ee Mon Sep 17 00:00:00 2001 From: Craig Alexander Date: Fri, 20 Jun 2025 12:33:43 -0400 Subject: [PATCH 03/10] Move npm install into its own docker stage (#999) --- Dockerfile | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index b8260679..25eec9ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,18 @@ # multi stage to build tube archivist # build python wheel, download and extract ffmpeg, copy into final image +FROM node:lts-alpine AS npm-builder +COPY frontend/package.json frontend/package-lock.json / +RUN npm i + FROM node:lts-alpine AS node-builder # RUN npm config set registry https://registry.npmjs.org/ +COPY --from=npm-builder ./node_modules /frontend/node_modules COPY ./frontend /frontend - WORKDIR /frontend -RUN npm i + RUN npm run build:deploy WORKDIR / @@ -54,9 +58,9 @@ RUN apt-get clean && apt-get -y update && apt-get -y install --no-install-recomm # install debug tools for testing environment RUN if [ "$INSTALL_DEBUG" ] ; then \ - apt-get -y update && apt-get -y install --no-install-recommends \ - vim htop bmon net-tools iputils-ping procps lsof \ - && pip install --user ipython pytest pytest-django \ + apt-get -y update && apt-get -y install --no-install-recommends \ + vim htop bmon net-tools iputils-ping procps lsof \ + && pip install --user ipython pytest pytest-django \ ; fi # make folders From b14309daebf3a3c69f4de615b069ff090185de8f Mon Sep 17 00:00:00 2001 From: MerlinScheurer Date: Sun, 22 Jun 2025 11:41:00 +0200 Subject: [PATCH 04/10] Fix do not send referrer when opening youtube, sponsorblock or returndislite links --- frontend/src/components/DownloadListItem.tsx | 6 ++++- frontend/src/components/VideoPlayer.tsx | 24 ++++++++++++++++---- frontend/src/pages/ChannelAbout.tsx | 8 +++++-- frontend/src/pages/Playlist.tsx | 1 + frontend/src/pages/SettingsApplication.tsx | 20 ++++++++++++---- frontend/src/pages/Video.tsx | 6 ++++- 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/DownloadListItem.tsx b/frontend/src/components/DownloadListItem.tsx index bb0a82e3..ff0273dd 100644 --- a/frontend/src/components/DownloadListItem.tsx +++ b/frontend/src/components/DownloadListItem.tsx @@ -47,7 +47,11 @@ const DownloadListItem = ({ download, setRefresh }: DownloadListItemProps) => { {!download.channel_indexed && {download.channel_name}} - +

{download.title}

diff --git a/frontend/src/components/VideoPlayer.tsx b/frontend/src/components/VideoPlayer.tsx index 7684e24a..001c5e7c 100644 --- a/frontend/src/components/VideoPlayer.tsx +++ b/frontend/src/components/VideoPlayer.tsx @@ -467,11 +467,19 @@ const VideoPlayer = ({

This video doesn't have any sponsor segments added. To add a segment go to{' '} - this video on YouTube + + this video on YouTube + {' '} and add a segment using the{' '} - SponsorBlock + + SponsorBlock + {' '} extension.

@@ -480,11 +488,19 @@ const VideoPlayer = ({

This video has unlocked sponsor segments. Go to{' '} - this video on YouTube + + this video on YouTube + {' '} and vote on the segments using the{' '} - SponsorBlock + + SponsorBlock + {' '} extension.

diff --git a/frontend/src/pages/ChannelAbout.tsx b/frontend/src/pages/ChannelAbout.tsx index 1ad1cf46..54898b92 100644 --- a/frontend/src/pages/ChannelAbout.tsx +++ b/frontend/src/pages/ChannelAbout.tsx @@ -130,7 +130,11 @@ const ChannelAbout = () => { {channel.channel_active && (

Youtube:{' '} - + Active

@@ -316,7 +320,7 @@ const ChannelAbout = () => {

Overwrite{' '} - + SponsorBlock

diff --git a/frontend/src/pages/Playlist.tsx b/frontend/src/pages/Playlist.tsx index 37657f64..f8affa20 100644 --- a/frontend/src/pages/Playlist.tsx +++ b/frontend/src/pages/Playlist.tsx @@ -180,6 +180,7 @@ const Playlist = () => { Active diff --git a/frontend/src/pages/SettingsApplication.tsx b/frontend/src/pages/SettingsApplication.tsx index f8e1a39b..594ef29c 100644 --- a/frontend/src/pages/SettingsApplication.tsx +++ b/frontend/src/pages/SettingsApplication.tsx @@ -779,7 +779,11 @@ const SettingsApplication = () => {
  • Make sure to contribute to this excellent project.
  • More details{' '} - + here . @@ -794,7 +798,11 @@ const SettingsApplication = () => {
  • Make sure to contribute to this excellent project.
  • More details{' '} - + here . @@ -831,7 +839,11 @@ const SettingsApplication = () => {

    Enable{' '} - + returnyoutubedislike

    @@ -846,7 +858,7 @@ const SettingsApplication = () => {

    Enable{' '} - + Sponsorblock

    diff --git a/frontend/src/pages/Video.tsx b/frontend/src/pages/Video.tsx index 785a6e23..68929f38 100644 --- a/frontend/src/pages/Video.tsx +++ b/frontend/src/pages/Video.tsx @@ -279,7 +279,11 @@ const Video = () => { {video.active && (

    Youtube:{' '} - + Active

    From d19190bf6a0228a7ed18e6ca692b8541be69aee9 Mon Sep 17 00:00:00 2001 From: MerlinScheurer Date: Sun, 22 Jun 2025 12:10:29 +0200 Subject: [PATCH 05/10] Add theater mode to normal video player --- frontend/src/components/VideoPlayer.tsx | 57 ++++++++++++++++++++++++- frontend/src/style.css | 30 +++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/VideoPlayer.tsx b/frontend/src/components/VideoPlayer.tsx index 001c5e7c..47a19977 100644 --- a/frontend/src/components/VideoPlayer.tsx +++ b/frontend/src/components/VideoPlayer.tsx @@ -126,6 +126,7 @@ const VideoPlayer = ({ const [searchParams] = useSearchParams(); const searchParamVideoProgress = searchParams.get('t'); + const theaterModeFromStorage = localStorage.getItem('theaterMode') === 'true'; const volumeFromStorage = Number(localStorage.getItem('playerVolume') ?? 1); const playBackSpeedFromStorage = Number(localStorage.getItem('playerSpeed') || 1); const playBackSpeedIndex = @@ -140,6 +141,8 @@ const VideoPlayer = ({ const [showHelpDialog, setShowHelpDialog] = useState(false); const [showInfoDialog, setShowInfoDialog] = useState(false); const [infoDialogContent, setInfoDialogContent] = useState(''); + const [isTheaterMode, setIsTheaterMode] = useState(theaterModeFromStorage); + const [theaterModeKeyPressed, setTheaterModeKeyPressed] = useState(false); const questionmarkPressed = useKeyPress('?'); const mutePressed = useKeyPress('m'); @@ -151,6 +154,8 @@ const VideoPlayer = ({ const arrowRightPressed = useKeyPress('ArrowRight'); const arrowLeftPressed = useKeyPress('ArrowLeft'); const pPausedPressed = useKeyPress('p'); + const theaterModePressed = useKeyPress('t'); + const escapePressed = useKeyPress('Escape'); const videoId = video.youtube_id; const videoUrl = video.media_url; @@ -345,10 +350,46 @@ const VideoPlayer = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [questionmarkPressed]); + useEffect(() => { + if (embed) { + return; + } + + if (theaterModePressed && !theaterModeKeyPressed) { + setTheaterModeKeyPressed(true); + + const newTheaterMode = !isTheaterMode; + setIsTheaterMode(newTheaterMode); + + localStorage.setItem('theaterMode', newTheaterMode.toString()); + + infoDialog(newTheaterMode ? 'Theater mode' : 'Normal mode'); + } else if (!theaterModePressed) { + setTheaterModeKeyPressed(false); + } + }, [theaterModePressed, isTheaterMode, theaterModeKeyPressed]); + + useEffect(() => { + if (embed) { + return; + } + + if (escapePressed && isTheaterMode) { + setIsTheaterMode(false); + + localStorage.setItem('theaterMode', 'false'); + + infoDialog('Normal mode'); + } + }, [escapePressed, isTheaterMode]); + return ( <> -
    -
    +
    +