diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4d6f23f..8b9b167 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -35,43 +35,8 @@ jobs: - name: Lint run: yarn run lint - - name: Build website - run: yarn run export - env: - NODE_ENV: production - - - uses: actions/upload-artifact@v3 - with: - name: output - path: out - - pages: - runs-on: ubuntu-latest - needs: test - steps: - - name: Setup - uses: actions/checkout@v2 - - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: "16.x" - cache: "yarn" - - - name: Install npm dependencies - run: yarn install - - - name: Build website - run: yarn run export - env: - NODE_ENV: production - - - name: Deploy to pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./out - cname: materialtube.guusvanmeerveld.dev + - name: Build + run: yarn run build docker: runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile index f3ea2f8..8a39276 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,7 @@ FROM node:16-alpine AS deps WORKDIR /app - COPY package.json yarn.lock ./ - RUN yarn install --frozen-lockfile @@ -12,15 +10,32 @@ FROM node:16-alpine AS builder WORKDIR /app COPY . . + COPY --from=deps /app/node_modules ./node_modules ENV NEXT_TELEMETRY_DISABLED 1; -ENV NODE_ENV "production" -RUN yarn export +RUN yarn build && yarn install --production --ignore-scripts --prefer-offline + + +FROM node:16-alpine AS runner + +WORKDIR /app + +ENV NODE_ENV production + +RUN addgroup -g 1001 -S nodejs +RUN adduser -S nextjs -u 1001 + +COPY --from=builder /app/next.config.js ./ +COPY --from=builder /app/next-i18next.config.js ./ +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/package.json ./package.json -FROM nginx:alpine AS runner +USER nextjs -COPY --from=builder /app/out /usr/share/nginx/html +EXPOSE 3000 -EXPOSE 80 \ No newline at end of file +CMD ["yarn", "start"] diff --git a/docker-compose.yml b/docker-compose.yml index 2e4f7b3..18a333f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,4 +5,4 @@ services: build: . container_name: material-tube ports: - - 3000:80 + - 3000:3000 diff --git a/package.json b/package.json index c30f987..7d6741a 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,11 @@ "repository": { "url": "https://github.com/Guusvanmeerveld/MaterialTube" }, - "cacheDirectories": [ - ".next/cache" - ], + "cacheDirectories": [".next/cache"], "scripts": { "dev": "next dev", "build": "next build", "start": "next start", - "export": "next build && next export", "lint": "next lint", "prettify": "prettier src --write" }, diff --git a/src/components/Player/Time.tsx b/src/components/Player/Time.tsx index 963b6de..cc64917 100644 --- a/src/components/Player/Time.tsx +++ b/src/components/Player/Time.tsx @@ -16,7 +16,10 @@ const Time: FC<{ const progress = useVideoState((state) => state.progress); return ( - + {formatTime(Math.round(progress))} <> / {formatTime(duration)} diff --git a/src/components/Player/index.tsx b/src/components/Player/index.tsx index 71ae2ff..5a88e5c 100644 --- a/src/components/Player/index.tsx +++ b/src/components/Player/index.tsx @@ -18,7 +18,7 @@ const Player: FC<{ captions: Caption[]; length: number; videoId: string; - sx: SxProps; + sx?: SxProps; }> = ({ formats, length: duration, sx }) => { const [settings] = useSettings(); @@ -40,7 +40,9 @@ const Player: FC<{ const pausedBy = useVideoState((state) => state.pausedBy); const videoStream = formats.find( - (format) => format.qualityLabel == "2160p" || format.qualityLabel == "1080p" + (format) => + format.qualityLabel == "2160p" || + format.qualityLabel == "1080p" )?.url; const audioStream = formats.find((format) => @@ -78,7 +80,8 @@ const Player: FC<{ const handleFinishedWaiting = (e: Event) => { setWaiting(false); - if (pausedBy == PausedBy.Player) setPlaying(VideoStatus.Playing); + if (pausedBy == PausedBy.Player) + setPlaying(VideoStatus.Playing); }; const onTimeUpdate = () => { @@ -105,13 +108,19 @@ const Player: FC<{ audio.srcObject = null; video.removeEventListener("waiting", handleWaiting); - video.removeEventListener("canplaythrough", handleFinishedWaiting); + video.removeEventListener( + "canplaythrough", + handleFinishedWaiting + ); video.removeEventListener("error", handleError); video.removeEventListener("pause", handlePause); video.removeEventListener("timeupdate", onTimeUpdate); audio.removeEventListener("waiting", handleWaiting); - audio.removeEventListener("canplaythrough", handleFinishedWaiting); + audio.removeEventListener( + "canplaythrough", + handleFinishedWaiting + ); audio.removeEventListener("pause", handlePause); }; @@ -119,18 +128,22 @@ const Player: FC<{ }, []); useEffect(() => { - setPlaying(settings.autoPlay ? VideoStatus.Playing : VideoStatus.Paused); + setPlaying( + settings.autoPlay + ? VideoStatus.Playing + : VideoStatus.Paused + ); }, [setPlaying, settings.autoPlay]); useEffect(() => { if (!videoRef.current || !audioRef.current) return; - if (playing == VideoStatus.Paused) { - videoRef.current.pause(); - audioRef.current.pause(); - } else { + if (playing == VideoStatus.Playing && !error && !waiting) { videoRef.current.play(); audioRef.current.play(); + } else { + videoRef.current.pause(); + audioRef.current.pause(); } }, [error, playing, waiting]); @@ -172,7 +185,8 @@ const Player: FC<{ src={videoStream} ref={videoRef} style={{ - height: "100%" + height: "100%", + width: "100%" }} autoPlay={playing == VideoStatus.Playing} > diff --git a/src/components/Video/Inline.tsx b/src/components/Video/Inline.tsx index 2644d0b..6fc591a 100644 --- a/src/components/Video/Inline.tsx +++ b/src/components/Video/Inline.tsx @@ -60,7 +60,12 @@ const Video: FC<{ video: VideoModel }> = ({ video }) => { - + @@ -99,16 +104,29 @@ const Video: FC<{ video: VideoModel }> = ({ video }) => { - + {isLoading && } {!isLoading && ( )} diff --git a/src/pages/404.tsx b/src/pages/404.tsx index bb8bc74..1a44ab3 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -15,9 +15,12 @@ const NotFound: NextPage = () => { /> - Page not found + + Page not found + - The page may have been moved or deleted. + The page may have been moved or + deleted. diff --git a/src/pages/settings.tsx b/src/pages/settings.tsx index 1d8fade..e4129a8 100644 --- a/src/pages/settings.tsx +++ b/src/pages/settings.tsx @@ -61,18 +61,35 @@ const InfoModal: FC<{ Stats for {settings.invidiousServer} - + Version: {data.version}

- Software name: {data.software.name}
- Software version: {data.software.version}
- Software branch: {data.software.branch}

- Is accepting registrations: {data.openRegistrations ? "Yes" : "No"} + Software name: {data.software.name}{" "} +
+ Software version:{" "} + {data.software.version}
+ Software branch: { + data.software.branch + }{" "} +

+ Is accepting registrations:{" "} + {data.openRegistrations ? "Yes" : "No"}

- Total users: {data.usage.users.total}
- Active in the past half year: {data.usage.users.activeHalfyear} + Total users: { + data.usage.users.total + }{" "} +
+ Active in the past half year:{" "} + {data.usage.users.activeHalfyear}
- Active in the past month: {data.usage.users.activeMonth}

- Stats updated at: {lastUpdated.toLocaleDateString()} -{" "} + Active in the past month:{" "} + { + data.usage.users.activeMonth + }

+ Stats updated at:{" "} + {lastUpdated.toLocaleDateString()} -{" "} {lastUpdated.toLocaleTimeString()}
@@ -92,7 +109,13 @@ const Setting: FC<{ title: string; description?: string }> = ({ {title} {description && ( - + {description} )} @@ -127,10 +150,13 @@ const Settings: NextPage = () => { const invidiousServerResponse = useMutation( "invidiousInstance", (server) => - axios.get(`https://${server}/api/v1/stats`).then((res) => res.data) + axios + .get(`https://${server}/api/v1/stats`) + .then((res) => res.data) ); - const allowsRegistrations = invidiousServerResponse.data?.openRegistrations; + const allowsRegistrations = + invidiousServerResponse.data?.openRegistrations; return ( <> @@ -146,7 +172,9 @@ const Settings: NextPage = () => { - Theme + + Theme + { color="primary" aria-label="outlined default button group" > - - - + + - + setSetting("primaryColor", color)} - selectedColor={settings.primaryColor} + setState={ + setPrimaryColorModal + } + isOpen={ + primaryColorModalIsOpen + } + setColor={(color) => + setSetting( + "primaryColor", + color + ) + } + selectedColor={ + settings.primaryColor + } /> - + setSetting("accentColor", color)} - selectedColor={settings.accentColor} + setState={ + setAccentColorModal + } + isOpen={ + accentColorModalIsOpen + } + setColor={(color) => + setSetting( + "accentColor", + color + ) + } + selectedColor={ + settings.accentColor + } /> - Player + + Player + - Data + + Data + @@ -218,10 +317,15 @@ const Settings: NextPage = () => { - invidiousServerResponse.mutate(settings.invidiousServer) + invidiousServerResponse.mutate( + settings.invidiousServer + ) } /> )} @@ -229,50 +333,111 @@ const Settings: NextPage = () => { !invidiousServerResponse.isLoading && ( <> setModalState(true)} - sx={{ color: green[800], cursor: "pointer" }} + onClick={() => + setModalState( + true + ) + } + sx={{ + color: green[800], + cursor: "pointer" + }} /> )} {invidiousServerResponse.error && ( - + + )} + {invidiousServerResponse.isLoading && ( + )} - {invidiousServerResponse.isLoading && } - - Server + + + Server + @@ -281,22 +446,43 @@ const Settings: NextPage = () => { title="Data Storage Location" description="Where your personal data will be stored" > - - Location + + + Location + - {settings.storageType != StorageType.Local && ( + {settings.storageType != + StorageType.Local && ( <> - {settings.storageType == "invidious" && allowsRegistrations && ( - - - - )} + {settings.storageType == + "invidious" && + allowsRegistrations && ( + + + + )} - {settings.storageType == StorageType.RemoteServer && ( + {settings.storageType == + StorageType.RemoteServer && ( - + )} { { const { query, isReady } = useRouter(); + const theme = useTheme(); + const videoId = query["v"]; const [settings] = useSettings(); @@ -59,7 +71,6 @@ const Watch: NextPage = () => { return ( <> - {data && ( <> @@ -69,10 +80,79 @@ const Watch: NextPage = () => { captions={data.captions} length={data.lengthSeconds} videoId={data.videoId} - sx={{ height: "75vh", margin: "auto", mt: 2 }} + sx={{ + height: "75vh", + margin: "auto", + mt: 2 + }} /> - - {data.title} + + + + {data.title} + + {abbreviateNumber(data.viewCount)} Views •{" "} + {new Date(data.published * 1000).toLocaleDateString()} + + + + + + + + +
+ + thumbnail.width == 100 + )?.url + } + alt={data.author} + sx={{ + mr: 2 + }} + /> + {data.author} + + + + + ") + }} + > )}