mirror of
https://github.com/movie-web/movie-web.git
synced 2024-12-27 09:31:50 +01:00
Merge branch 'v4' into chromecast
This commit is contained in:
commit
fcebbf404d
@ -52,6 +52,7 @@ module.exports = {
|
|||||||
"no-await-in-loop": "off",
|
"no-await-in-loop": "off",
|
||||||
"no-nested-ternary": "off",
|
"no-nested-ternary": "off",
|
||||||
"prefer-destructuring": "off",
|
"prefer-destructuring": "off",
|
||||||
|
"no-param-reassign": "off",
|
||||||
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
|
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
|
||||||
"react/jsx-filename-extension": [
|
"react/jsx-filename-extension": [
|
||||||
"error",
|
"error",
|
||||||
|
8
.github/workflows/deploying.yml
vendored
8
.github/workflows/deploying.yml
vendored
@ -18,13 +18,13 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
cache: 'yarn'
|
cache: 'pnpm'
|
||||||
|
|
||||||
- name: Install Yarn packages
|
- name: Install pnpm packages
|
||||||
run: yarn install
|
run: pnpm install
|
||||||
|
|
||||||
- name: Build project
|
- name: Build project
|
||||||
run: yarn build
|
run: pnpm run build
|
||||||
|
|
||||||
- name: Upload production-ready build files
|
- name: Upload production-ready build files
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
|
16
.github/workflows/linting_testing.yml
vendored
16
.github/workflows/linting_testing.yml
vendored
@ -20,13 +20,13 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
cache: 'yarn'
|
cache: 'pnpm'
|
||||||
|
|
||||||
- name: Install Yarn packages
|
- name: Install pnpm packages
|
||||||
run: yarn install
|
run: pnpm install
|
||||||
|
|
||||||
- name: Run ESLint
|
- name: Run ESLint
|
||||||
run: yarn lint
|
run: pnpm run lint
|
||||||
|
|
||||||
building:
|
building:
|
||||||
name: Build project
|
name: Build project
|
||||||
@ -40,10 +40,10 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
cache: 'yarn'
|
cache: 'pnpm'
|
||||||
|
|
||||||
- name: Install Yarn packages
|
- name: Install pnpm packages
|
||||||
run: yarn install
|
run: pnpm install
|
||||||
|
|
||||||
- name: Build Project
|
- name: Build Project
|
||||||
run: yarn build
|
run: pnpm run build
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -20,9 +20,9 @@ dev-dist
|
|||||||
.env.production.local
|
.env.production.local
|
||||||
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
|
# other package managers
|
||||||
|
yarn.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
# config
|
# config
|
||||||
|
@ -34,16 +34,16 @@ Check it out here: [https://github.com/movie-web/movie-web/blob/dev/SELFHOSTING.
|
|||||||
## Running locally for development
|
## Running locally for development
|
||||||
|
|
||||||
To run this project locally for contributing or testing, run the following commands:
|
To run this project locally for contributing or testing, run the following commands:
|
||||||
<h5><b>note: must use yarn to install packages and run NodeJS 16</b></h5>
|
<h5><b>note: must use pnpm to install packages and run NodeJS 16 (install with `npm i -g pnpm`)</b></h5>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/movie-web/movie-web
|
git clone https://github.com/movie-web/movie-web
|
||||||
cd movie-web
|
cd movie-web
|
||||||
yarn install
|
pnpm install
|
||||||
yarn dev
|
pnpm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
To build production files, simply run `yarn build`.
|
To build production files, simply run `pnpm run build`.
|
||||||
|
|
||||||
You'll need to deploy a cloudflare service worker as well. Check the [selfhosting guide](https://github.com/movie-web/movie-web/blob/dev/SELFHOSTING.md) on how to run the service worker. Afterwards you can make a `.env` file and put in the URL. (see `example.env` for an example)
|
You'll need to deploy a cloudflare service worker as well. Check the [selfhosting guide](https://github.com/movie-web/movie-web/blob/dev/SELFHOSTING.md) on how to run the service worker. Afterwards you can make a `.env` file and put in the URL. (see `example.env` for an example)
|
||||||
|
|
||||||
|
13
dockerfile
13
dockerfile
@ -1,10 +1,15 @@
|
|||||||
FROM node:16.15-alpine as build
|
FROM node:16.15-alpine as build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV PATH /app/node_modules/.bin:$PATH
|
ENV PNPM_HOME="/pnpm"
|
||||||
COPY package*.json ./
|
ENV PATH="$PNPM_HOME:$PATH"
|
||||||
RUN yarn install
|
RUN corepack enable
|
||||||
|
|
||||||
|
COPY package.json ./
|
||||||
|
COPY pnpm-lock.yaml ./
|
||||||
|
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
|
||||||
|
|
||||||
COPY . ./
|
COPY . ./
|
||||||
RUN yarn build
|
RUN pnpm run build
|
||||||
|
|
||||||
# production environment
|
# production environment
|
||||||
FROM nginx:stable-alpine
|
FROM nginx:stable-alpine
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://movie-web.app",
|
"homepage": "https://movie-web.app",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/auto-animate": "^1.0.0-beta.5",
|
"@formkit/auto-animate": "^0.7.0",
|
||||||
"@headlessui/react": "^1.5.0",
|
"@headlessui/react": "^1.5.0",
|
||||||
"@react-spring/web": "^9.7.1",
|
"@react-spring/web": "^9.7.1",
|
||||||
"@sentry/integrations": "^7.49.0",
|
"@sentry/integrations": "^7.49.0",
|
||||||
@ -19,6 +19,7 @@
|
|||||||
"hls.js": "^1.0.7",
|
"hls.js": "^1.0.7",
|
||||||
"i18next": "^22.4.5",
|
"i18next": "^22.4.5",
|
||||||
"i18next-browser-languagedetector": "^7.0.1",
|
"i18next-browser-languagedetector": "^7.0.1",
|
||||||
|
"immer": "^10.0.2",
|
||||||
"json5": "^2.2.0",
|
"json5": "^2.2.0",
|
||||||
"lodash.throttle": "^4.1.1",
|
"lodash.throttle": "^4.1.1",
|
||||||
"nanoid": "^4.0.0",
|
"nanoid": "^4.0.0",
|
||||||
@ -35,7 +36,8 @@
|
|||||||
"react-use": "^17.4.0",
|
"react-use": "^17.4.0",
|
||||||
"slugify": "^1.6.6",
|
"slugify": "^1.6.6",
|
||||||
"subsrt-ts": "^2.1.1",
|
"subsrt-ts": "^2.1.1",
|
||||||
"unpacker": "^1.0.1"
|
"unpacker": "^1.0.1",
|
||||||
|
"zustand": "^4.3.9"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@ -44,7 +46,8 @@
|
|||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"lint": "eslint --ext .tsx,.ts src",
|
"lint": "eslint --ext .tsx,.ts src",
|
||||||
"lint:fix": "eslint --fix --ext .tsx,.ts src",
|
"lint:fix": "eslint --fix --ext .tsx,.ts src",
|
||||||
"lint:report": "eslint --ext .tsx,.ts --output-file eslint_report.json --format json src"
|
"lint:report": "eslint --ext .tsx,.ts --output-file eslint_report.json --format json src",
|
||||||
|
"preinstall": "npx -y only-allow pnpm"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
6729
pnpm-lock.yaml
generated
Normal file
6729
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,34 +1,34 @@
|
|||||||
import { ReactNode, useCallback, useState } from "react";
|
import { ReactNode, useCallback, useState } from "react";
|
||||||
|
|
||||||
import { Transition } from "@/components/Transition";
|
import { AirplayAction } from "@/_oldvideo/components/actions/AirplayAction";
|
||||||
import { useIsMobile } from "@/hooks/useIsMobile";
|
import { BackdropAction } from "@/_oldvideo/components/actions/BackdropAction";
|
||||||
import { AirplayAction } from "@/video/components/actions/AirplayAction";
|
import { CastingTextAction } from "@/_oldvideo/components/actions/CastingTextAction";
|
||||||
import { BackdropAction } from "@/video/components/actions/BackdropAction";
|
import { ChromecastAction } from "@/_oldvideo/components/actions/ChromecastAction";
|
||||||
import { CastingTextAction } from "@/video/components/actions/CastingTextAction";
|
import { FullscreenAction } from "@/_oldvideo/components/actions/FullscreenAction";
|
||||||
import { ChromecastAction } from "@/video/components/actions/ChromecastAction";
|
import { HeaderAction } from "@/_oldvideo/components/actions/HeaderAction";
|
||||||
import { FullscreenAction } from "@/video/components/actions/FullscreenAction";
|
import { KeyboardShortcutsAction } from "@/_oldvideo/components/actions/KeyboardShortcutsAction";
|
||||||
import { HeaderAction } from "@/video/components/actions/HeaderAction";
|
import { LoadingAction } from "@/_oldvideo/components/actions/LoadingAction";
|
||||||
import { KeyboardShortcutsAction } from "@/video/components/actions/KeyboardShortcutsAction";
|
import { MiddlePauseAction } from "@/_oldvideo/components/actions/MiddlePauseAction";
|
||||||
import { LoadingAction } from "@/video/components/actions/LoadingAction";
|
import { MobileCenterAction } from "@/_oldvideo/components/actions/MobileCenterAction";
|
||||||
import { MiddlePauseAction } from "@/video/components/actions/MiddlePauseAction";
|
import { PageTitleAction } from "@/_oldvideo/components/actions/PageTitleAction";
|
||||||
import { MobileCenterAction } from "@/video/components/actions/MobileCenterAction";
|
import { PauseAction } from "@/_oldvideo/components/actions/PauseAction";
|
||||||
import { PageTitleAction } from "@/video/components/actions/PageTitleAction";
|
import { PictureInPictureAction } from "@/_oldvideo/components/actions/PictureInPictureAction";
|
||||||
import { PauseAction } from "@/video/components/actions/PauseAction";
|
import { ProgressAction } from "@/_oldvideo/components/actions/ProgressAction";
|
||||||
import { PictureInPictureAction } from "@/video/components/actions/PictureInPictureAction";
|
import { SeriesSelectionAction } from "@/_oldvideo/components/actions/SeriesSelectionAction";
|
||||||
import { ProgressAction } from "@/video/components/actions/ProgressAction";
|
import { ShowTitleAction } from "@/_oldvideo/components/actions/ShowTitleAction";
|
||||||
import { SeriesSelectionAction } from "@/video/components/actions/SeriesSelectionAction";
|
import { SkipTimeAction } from "@/_oldvideo/components/actions/SkipTimeAction";
|
||||||
import { ShowTitleAction } from "@/video/components/actions/ShowTitleAction";
|
import { TimeAction } from "@/_oldvideo/components/actions/TimeAction";
|
||||||
import { SkipTimeAction } from "@/video/components/actions/SkipTimeAction";
|
import { VolumeAction } from "@/_oldvideo/components/actions/VolumeAction";
|
||||||
import { TimeAction } from "@/video/components/actions/TimeAction";
|
import { VideoPlayerError } from "@/_oldvideo/components/parts/VideoPlayerError";
|
||||||
import { VolumeAction } from "@/video/components/actions/VolumeAction";
|
import { PopoutProviderAction } from "@/_oldvideo/components/popouts/PopoutProviderAction";
|
||||||
import { VideoPlayerError } from "@/video/components/parts/VideoPlayerError";
|
|
||||||
import { PopoutProviderAction } from "@/video/components/popouts/PopoutProviderAction";
|
|
||||||
import {
|
import {
|
||||||
VideoPlayerBase,
|
VideoPlayerBase,
|
||||||
VideoPlayerBaseProps,
|
VideoPlayerBaseProps,
|
||||||
} from "@/video/components/VideoPlayerBase";
|
} from "@/_oldvideo/components/VideoPlayerBase";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { Transition } from "@/components/Transition";
|
||||||
|
import { useIsMobile } from "@/hooks/useIsMobile";
|
||||||
|
|
||||||
import { CaptionRendererAction } from "./actions/CaptionRendererAction";
|
import { CaptionRendererAction } from "./actions/CaptionRendererAction";
|
||||||
import { DividerAction } from "./actions/DividerAction";
|
import { DividerAction } from "./actions/DividerAction";
|
@ -1,10 +1,10 @@
|
|||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
|
|
||||||
import { CastingInternal } from "@/video/components/internal/CastingInternal";
|
import { CastingInternal } from "@/_oldvideo/components/internal/CastingInternal";
|
||||||
import { WrapperRegisterInternal } from "@/video/components/internal/WrapperRegisterInternal";
|
import { WrapperRegisterInternal } from "@/_oldvideo/components/internal/WrapperRegisterInternal";
|
||||||
import { VideoErrorBoundary } from "@/video/components/parts/VideoErrorBoundary";
|
import { VideoErrorBoundary } from "@/_oldvideo/components/parts/VideoErrorBoundary";
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
|
|
||||||
import { MetaAction } from "./actions/MetaAction";
|
import { MetaAction } from "./actions/MetaAction";
|
||||||
import ThumbnailGeneratorInternal from "./internal/ThumbnailGeneratorInternal";
|
import ThumbnailGeneratorInternal from "./internal/ThumbnailGeneratorInternal";
|
@ -1,9 +1,9 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useMisc } from "@/video/state/logic/misc";
|
|
||||||
|
|
||||||
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
|
|
||||||
interface BackdropActionProps {
|
interface BackdropActionProps {
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
@ -1,8 +1,8 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useMisc } from "@/video/state/logic/misc";
|
|
||||||
|
|
||||||
export function CastingTextAction() {
|
export function CastingTextAction() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
@ -1,9 +1,9 @@
|
|||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
import { VideoPlayerIconButton } from "@/_oldvideo/components/parts/VideoPlayerIconButton";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { VideoPlayerIconButton } from "@/video/components/parts/VideoPlayerIconButton";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useMisc } from "@/video/state/logic/misc";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
@ -1,6 +1,6 @@
|
|||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
import { MWMediaType } from "@/backend/metadata/types/mw";
|
import { MWMediaType } from "@/backend/metadata/types/mw";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
|
||||||
|
|
||||||
export function DividerAction() {
|
export function DividerAction() {
|
||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
@ -1,10 +1,10 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { canFullscreen } from "@/utils/detectFeatures";
|
import { canFullscreen } from "@/utils/detectFeatures";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
|
||||||
|
|
||||||
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
import { VideoPlayerHeader } from "@/video/components/parts/VideoPlayerHeader";
|
import { VideoPlayerHeader } from "@/_oldvideo/components/parts/VideoPlayerHeader";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
@ -1,12 +1,12 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
import { getPlayerState } from "@/_oldvideo/state/cache";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
|
import { useProgress } from "@/_oldvideo/state/logic/progress";
|
||||||
import { useVolumeControl } from "@/hooks/useVolumeToggle";
|
import { useVolumeControl } from "@/hooks/useVolumeToggle";
|
||||||
import { getPlayerState } from "@/video/state/cache";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
import { useProgress } from "@/video/state/logic/progress";
|
|
||||||
|
|
||||||
export function KeyboardShortcutsAction() {
|
export function KeyboardShortcutsAction() {
|
||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
@ -1,7 +1,7 @@
|
|||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
|
import { useMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
import { Spinner } from "@/components/layout/Spinner";
|
import { Spinner } from "@/components/layout/Spinner";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
import { useMisc } from "@/video/state/logic/misc";
|
|
||||||
|
|
||||||
export function LoadingAction() {
|
export function LoadingAction() {
|
||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
@ -1,13 +1,16 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import {
|
import {
|
||||||
VideoMediaPlayingEvent,
|
VideoMediaPlayingEvent,
|
||||||
useMediaPlaying,
|
useMediaPlaying,
|
||||||
} from "@/video/state/logic/mediaplaying";
|
} from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
import { VideoProgressEvent, useProgress } from "@/video/state/logic/progress";
|
import {
|
||||||
import { VideoPlayerMeta } from "@/video/state/types";
|
VideoProgressEvent,
|
||||||
|
useProgress,
|
||||||
|
} from "@/_oldvideo/state/logic/progress";
|
||||||
|
import { VideoPlayerMeta } from "@/_oldvideo/state/types";
|
||||||
|
|
||||||
export type WindowMeta = {
|
export type WindowMeta = {
|
||||||
media: VideoPlayerMeta;
|
media: VideoPlayerMeta;
|
@ -1,9 +1,9 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
|
|
||||||
export function MiddlePauseAction() {
|
export function MiddlePauseAction() {
|
||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
@ -1,10 +1,10 @@
|
|||||||
import { PauseAction } from "@/video/components/actions/PauseAction";
|
import { PauseAction } from "@/_oldvideo/components/actions/PauseAction";
|
||||||
import {
|
import {
|
||||||
SkipTimeBackwardAction,
|
SkipTimeBackwardAction,
|
||||||
SkipTimeForwardAction,
|
SkipTimeForwardAction,
|
||||||
} from "@/video/components/actions/SkipTimeAction";
|
} from "@/_oldvideo/components/actions/SkipTimeAction";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
|
|
||||||
export function MobileCenterAction() {
|
export function MobileCenterAction() {
|
||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
@ -1,6 +1,6 @@
|
|||||||
import { Helmet } from "react-helmet";
|
import { Helmet } from "react-helmet";
|
||||||
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
|
||||||
import { useCurrentSeriesEpisodeInfo } from "../hooks/useCurrentSeriesEpisodeInfo";
|
import { useCurrentSeriesEpisodeInfo } from "../hooks/useCurrentSeriesEpisodeInfo";
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
|
|
||||||
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
||||||
|
|
@ -1,14 +1,14 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { useIsMobile } from "@/hooks/useIsMobile";
|
import { useIsMobile } from "@/hooks/useIsMobile";
|
||||||
import {
|
import {
|
||||||
canPictureInPicture,
|
canPictureInPicture,
|
||||||
canWebkitPictureInPicture,
|
canWebkitPictureInPicture,
|
||||||
} from "@/utils/detectFeatures";
|
} from "@/utils/detectFeatures";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
|
|
||||||
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
||||||
|
|
@ -1,15 +1,15 @@
|
|||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
import { getPlayerState } from "@/_oldvideo/state/cache";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useProgress } from "@/_oldvideo/state/logic/progress";
|
||||||
import {
|
import {
|
||||||
MouseActivity,
|
MouseActivity,
|
||||||
makePercentage,
|
makePercentage,
|
||||||
makePercentageString,
|
makePercentageString,
|
||||||
useProgressBar,
|
useProgressBar,
|
||||||
} from "@/hooks/useProgressBar";
|
} from "@/hooks/useProgressBar";
|
||||||
import { getPlayerState } from "@/video/state/cache";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useProgress } from "@/video/state/logic/progress";
|
|
||||||
|
|
||||||
import ThumbnailAction from "./ThumbnailAction";
|
import ThumbnailAction from "./ThumbnailAction";
|
||||||
|
|
@ -1,13 +1,13 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { VideoPlayerIconButton } from "@/_oldvideo/components/parts/VideoPlayerIconButton";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
import { MWMediaType } from "@/backend/metadata/types/mw";
|
import { MWMediaType } from "@/backend/metadata/types/mw";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { FloatingAnchor } from "@/components/popout/FloatingAnchor";
|
import { FloatingAnchor } from "@/components/popout/FloatingAnchor";
|
||||||
import { VideoPlayerIconButton } from "@/video/components/parts/VideoPlayerIconButton";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
@ -1,12 +1,12 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { VideoPlayerIconButton } from "@/_oldvideo/components/parts/VideoPlayerIconButton";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { FloatingAnchor } from "@/components/popout/FloatingAnchor";
|
import { FloatingAnchor } from "@/components/popout/FloatingAnchor";
|
||||||
import { useIsMobile } from "@/hooks/useIsMobile";
|
import { useIsMobile } from "@/hooks/useIsMobile";
|
||||||
import { VideoPlayerIconButton } from "@/video/components/parts/VideoPlayerIconButton";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
@ -1,4 +1,4 @@
|
|||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
|
||||||
import { useCurrentSeriesEpisodeInfo } from "../hooks/useCurrentSeriesEpisodeInfo";
|
import { useCurrentSeriesEpisodeInfo } from "../hooks/useCurrentSeriesEpisodeInfo";
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useProgress } from "@/_oldvideo/state/logic/progress";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useProgress } from "@/video/state/logic/progress";
|
|
||||||
|
|
||||||
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
import { VideoPlayerIconButton } from "../parts/VideoPlayerIconButton";
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
import { RefObject, useMemo } from "react";
|
import { RefObject, useMemo } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { VideoProgressEvent } from "@/_oldvideo/state/logic/progress";
|
||||||
|
import { useSource } from "@/_oldvideo/state/logic/source";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
import { formatSeconds } from "@/utils/formatSeconds";
|
import { formatSeconds } from "@/utils/formatSeconds";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { VideoProgressEvent } from "@/video/state/logic/progress";
|
|
||||||
import { useSource } from "@/video/state/logic/source";
|
|
||||||
|
|
||||||
const THUMBNAIL_HEIGHT = 100;
|
const THUMBNAIL_HEIGHT = 100;
|
||||||
function position(
|
function position(
|
@ -1,13 +1,13 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
|
import { useProgress } from "@/_oldvideo/state/logic/progress";
|
||||||
|
import { VideoPlayerTimeFormat } from "@/_oldvideo/state/types";
|
||||||
import { useIsMobile } from "@/hooks/useIsMobile";
|
import { useIsMobile } from "@/hooks/useIsMobile";
|
||||||
import { formatSeconds } from "@/utils/formatSeconds";
|
import { formatSeconds } from "@/utils/formatSeconds";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
import { useProgress } from "@/video/state/logic/progress";
|
|
||||||
import { VideoPlayerTimeFormat } from "@/video/state/types";
|
|
||||||
|
|
||||||
function durationExceedsHour(secs: number): boolean {
|
function durationExceedsHour(secs: number): boolean {
|
||||||
return secs > 60 * 60;
|
return secs > 60 * 60;
|
@ -1,5 +1,9 @@
|
|||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
import {
|
import {
|
||||||
makePercentage,
|
makePercentage,
|
||||||
@ -8,10 +12,6 @@ import {
|
|||||||
} from "@/hooks/useProgressBar";
|
} from "@/hooks/useProgressBar";
|
||||||
import { useVolumeControl } from "@/hooks/useVolumeToggle";
|
import { useVolumeControl } from "@/hooks/useVolumeToggle";
|
||||||
import { canChangeVolume } from "@/utils/detectFeatures";
|
import { canChangeVolume } from "@/utils/detectFeatures";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
@ -1,7 +1,7 @@
|
|||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
|
|
||||||
export function VolumeAdjustedAction() {
|
export function VolumeAdjustedAction() {
|
||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
@ -1,11 +1,11 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
|
import { useSource } from "@/_oldvideo/state/logic/source";
|
||||||
import { MWStreamType } from "@/backend/helpers/streams";
|
import { MWStreamType } from "@/backend/helpers/streams";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { normalizeTitle } from "@/utils/normalizeTitle";
|
import { normalizeTitle } from "@/utils/normalizeTitle";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
|
||||||
import { useSource } from "@/video/state/logic/source";
|
|
||||||
|
|
||||||
import { PopoutListAction } from "../../popouts/PopoutUtils";
|
import { PopoutListAction } from "../../popouts/PopoutUtils";
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { useSource } from "@/video/state/logic/source";
|
import { useSource } from "@/_oldvideo/state/logic/source";
|
||||||
|
|
||||||
export function QualityDisplayAction() {
|
export function QualityDisplayAction() {
|
||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
@ -1,10 +1,10 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { VideoPlayerMeta } from "@/_oldvideo/state/types";
|
||||||
import { MWCaption } from "@/backend/helpers/streams";
|
import { MWCaption } from "@/backend/helpers/streams";
|
||||||
import { MWSeasonWithEpisodeMeta } from "@/backend/metadata/types/mw";
|
import { MWSeasonWithEpisodeMeta } from "@/backend/metadata/types/mw";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { VideoPlayerMeta } from "@/video/state/types";
|
|
||||||
|
|
||||||
interface MetaControllerProps {
|
interface MetaControllerProps {
|
||||||
data?: VideoPlayerMeta;
|
data?: VideoPlayerMeta;
|
@ -1,12 +1,12 @@
|
|||||||
import throttle from "lodash.throttle";
|
import throttle from "lodash.throttle";
|
||||||
import { useEffect, useMemo, useRef } from "react";
|
import { useEffect, useMemo, useRef } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
|
import { useMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
|
import { useProgress } from "@/_oldvideo/state/logic/progress";
|
||||||
import { useQueryParams } from "@/hooks/useQueryParams";
|
import { useQueryParams } from "@/hooks/useQueryParams";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
import { useMisc } from "@/video/state/logic/misc";
|
|
||||||
import { useProgress } from "@/video/state/logic/progress";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
startAt?: number;
|
startAt?: number;
|
@ -1,8 +1,8 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
|
|
||||||
interface SeriesControllerProps {
|
interface SeriesControllerProps {
|
||||||
onSelect?: (state: { episodeId?: string; seasonId?: string }) => void;
|
onSelect?: (state: { episodeId?: string; seasonId?: string }) => void;
|
@ -1,5 +1,8 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
import { useInitialized } from "@/_oldvideo/components/hooks/useInitialized";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
import { getCaptionUrl, makeCaptionId } from "@/backend/helpers/captions";
|
import { getCaptionUrl, makeCaptionId } from "@/backend/helpers/captions";
|
||||||
import {
|
import {
|
||||||
MWCaption,
|
MWCaption,
|
||||||
@ -8,9 +11,6 @@ import {
|
|||||||
} from "@/backend/helpers/streams";
|
} from "@/backend/helpers/streams";
|
||||||
import { captionLanguages } from "@/setup/iso6391";
|
import { captionLanguages } from "@/setup/iso6391";
|
||||||
import { useSettings } from "@/state/settings";
|
import { useSettings } from "@/state/settings";
|
||||||
import { useInitialized } from "@/video/components/hooks/useInitialized";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
|
|
||||||
interface SourceControllerProps {
|
interface SourceControllerProps {
|
||||||
source: string;
|
source: string;
|
@ -1,8 +1,8 @@
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
import { MWMediaType } from "@/backend/metadata/types/mw";
|
import { MWMediaType } from "@/backend/metadata/types/mw";
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
|
||||||
|
|
||||||
export function useCurrentSeriesEpisodeInfo(descriptor: string) {
|
export function useCurrentSeriesEpisodeInfo(descriptor: string) {
|
||||||
const meta = useMeta(descriptor);
|
const meta = useMeta(descriptor);
|
@ -1,6 +1,6 @@
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
|
||||||
import { useMisc } from "@/video/state/logic/misc";
|
import { useMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
|
|
||||||
export function useInitialized(descriptor: string): { initialized: boolean } {
|
export function useInitialized(descriptor: string): { initialized: boolean } {
|
||||||
const misc = useMisc(descriptor);
|
const misc = useMisc(descriptor);
|
@ -1,8 +1,8 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import { useHistory, useLocation } from "react-router-dom";
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
|
|
||||||
import { ControlMethods, useControls } from "@/video/state/logic/controls";
|
import { ControlMethods, useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
|
||||||
function syncRouteToPopout(
|
function syncRouteToPopout(
|
||||||
location: ReturnType<typeof useLocation>,
|
location: ReturnType<typeof useLocation>,
|
@ -1,11 +1,14 @@
|
|||||||
import { useEffect, useMemo, useRef } from "react";
|
import { useEffect, useMemo, useRef } from "react";
|
||||||
|
|
||||||
|
import { getPlayerState } from "@/_oldvideo/state/cache";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { updateMisc, useMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
|
import { createCastingStateProvider } from "@/_oldvideo/state/providers/castingStateProvider";
|
||||||
|
import {
|
||||||
|
setProvider,
|
||||||
|
unsetStateProvider,
|
||||||
|
} from "@/_oldvideo/state/providers/utils";
|
||||||
import { useChromecastAvailable } from "@/hooks/useChromecastAvailable";
|
import { useChromecastAvailable } from "@/hooks/useChromecastAvailable";
|
||||||
import { getPlayerState } from "@/video/state/cache";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { updateMisc, useMisc } from "@/video/state/logic/misc";
|
|
||||||
import { createCastingStateProvider } from "@/video/state/providers/castingStateProvider";
|
|
||||||
import { setProvider, unsetStateProvider } from "@/video/state/providers/utils";
|
|
||||||
|
|
||||||
export function CastingInternal() {
|
export function CastingInternal() {
|
||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
@ -1,11 +1,11 @@
|
|||||||
import Hls from "hls.js";
|
import Hls from "hls.js";
|
||||||
import { RefObject, useCallback, useEffect, useRef, useState } from "react";
|
import { RefObject, useCallback, useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
import { getPlayerState } from "@/_oldvideo/state/cache";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { updateSource, useSource } from "@/_oldvideo/state/logic/source";
|
||||||
|
import { Thumbnail } from "@/_oldvideo/state/types";
|
||||||
import { MWStreamType } from "@/backend/helpers/streams";
|
import { MWStreamType } from "@/backend/helpers/streams";
|
||||||
import { getPlayerState } from "@/video/state/cache";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { updateSource, useSource } from "@/video/state/logic/source";
|
|
||||||
import { Thumbnail } from "@/video/state/types";
|
|
||||||
|
|
||||||
async function* generate(
|
async function* generate(
|
||||||
videoRef: RefObject<HTMLVideoElement>,
|
videoRef: RefObject<HTMLVideoElement>,
|
||||||
@ -54,6 +54,7 @@ export default function ThumbnailGeneratorInternal() {
|
|||||||
const descriptor = useVideoPlayerDescriptor();
|
const descriptor = useVideoPlayerDescriptor();
|
||||||
const source = useSource(descriptor);
|
const source = useSource(descriptor);
|
||||||
|
|
||||||
|
// TODO fix memory leak
|
||||||
const videoRef = useRef<HTMLVideoElement>(document.createElement("video"));
|
const videoRef = useRef<HTMLVideoElement>(document.createElement("video"));
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(document.createElement("canvas"));
|
const canvasRef = useRef<HTMLCanvasElement>(document.createElement("canvas"));
|
||||||
const hlsRef = useRef<Hls>(new Hls());
|
const hlsRef = useRef<Hls>(new Hls());
|
@ -1,10 +1,13 @@
|
|||||||
import { useEffect, useMemo, useRef } from "react";
|
import { useEffect, useMemo, useRef } from "react";
|
||||||
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
import { useMisc } from "@/video/state/logic/misc";
|
import { useMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
import { setProvider, unsetStateProvider } from "@/video/state/providers/utils";
|
import {
|
||||||
import { createVideoStateProvider } from "@/video/state/providers/videoStateProvider";
|
setProvider,
|
||||||
|
unsetStateProvider,
|
||||||
|
} from "@/_oldvideo/state/providers/utils";
|
||||||
|
import { createVideoStateProvider } from "@/_oldvideo/state/providers/videoStateProvider";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
autoPlay?: boolean;
|
autoPlay?: boolean;
|
@ -1,8 +1,8 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
import { getPlayerState } from "@/video/state/cache";
|
import { getPlayerState } from "@/_oldvideo/state/cache";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { updateMisc } from "@/video/state/logic/misc";
|
import { updateMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
|
|
||||||
export function WrapperRegisterInternal(props: {
|
export function WrapperRegisterInternal(props: {
|
||||||
wrapper: HTMLDivElement | null;
|
wrapper: HTMLDivElement | null;
|
@ -1,6 +1,6 @@
|
|||||||
import { Component } from "react";
|
import { Component } from "react";
|
||||||
|
import type { ReactNode } from "react";
|
||||||
import { Trans } from "react-i18next";
|
import { Trans } from "react-i18next";
|
||||||
import type { ReactNode } from "react-router-dom/node_modules/@types/react/index";
|
|
||||||
|
|
||||||
import { MWMediaMeta } from "@/backend/metadata/types/mw";
|
import { MWMediaMeta } from "@/backend/metadata/types/mw";
|
||||||
import { ErrorMessage } from "@/components/layout/ErrorBoundary";
|
import { ErrorMessage } from "@/components/layout/ErrorBoundary";
|
@ -1,11 +1,11 @@
|
|||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useError } from "@/_oldvideo/state/logic/error";
|
||||||
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
import { IconPatch } from "@/components/buttons/IconPatch";
|
import { IconPatch } from "@/components/buttons/IconPatch";
|
||||||
import { Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { Title } from "@/components/text/Title";
|
import { Title } from "@/components/text/Title";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useError } from "@/video/state/logic/error";
|
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
|
||||||
|
|
||||||
import { VideoPlayerHeader } from "./VideoPlayerHeader";
|
import { VideoPlayerHeader } from "./VideoPlayerHeader";
|
||||||
|
|
@ -1,5 +1,7 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { AirplayAction } from "@/_oldvideo/components/actions/AirplayAction";
|
||||||
|
import { ChromecastAction } from "@/_oldvideo/components/actions/ChromecastAction";
|
||||||
import { MWMediaMeta } from "@/backend/metadata/types/mw";
|
import { MWMediaMeta } from "@/backend/metadata/types/mw";
|
||||||
import { IconPatch } from "@/components/buttons/IconPatch";
|
import { IconPatch } from "@/components/buttons/IconPatch";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
@ -10,8 +12,6 @@ import {
|
|||||||
getIfBookmarkedFromPortable,
|
getIfBookmarkedFromPortable,
|
||||||
useBookmarkContext,
|
useBookmarkContext,
|
||||||
} from "@/state/bookmark";
|
} from "@/state/bookmark";
|
||||||
import { AirplayAction } from "@/video/components/actions/AirplayAction";
|
|
||||||
import { ChromecastAction } from "@/video/components/actions/ChromecastAction";
|
|
||||||
|
|
||||||
interface VideoPlayerHeaderProps {
|
interface VideoPlayerHeaderProps {
|
||||||
media?: MWMediaMeta;
|
media?: MWMediaMeta;
|
@ -1,8 +1,8 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
@ -1,6 +1,10 @@
|
|||||||
import { useMemo, useRef } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
|
import { useSource } from "@/_oldvideo/state/logic/source";
|
||||||
import {
|
import {
|
||||||
customCaption,
|
customCaption,
|
||||||
getCaptionUrl,
|
getCaptionUrl,
|
||||||
@ -14,10 +18,6 @@ import { FloatingCardView } from "@/components/popout/FloatingCard";
|
|||||||
import { FloatingView } from "@/components/popout/FloatingView";
|
import { FloatingView } from "@/components/popout/FloatingView";
|
||||||
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
||||||
import { useLoading } from "@/hooks/useLoading";
|
import { useLoading } from "@/hooks/useLoading";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
|
||||||
import { useSource } from "@/video/state/logic/source";
|
|
||||||
|
|
||||||
import { PopoutListEntry, PopoutSection } from "./PopoutUtils";
|
import { PopoutListEntry, PopoutSection } from "./PopoutUtils";
|
||||||
|
|
@ -2,6 +2,9 @@ import { useCallback, useMemo, useState } from "react";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
import { getMetaFromId } from "@/backend/metadata/getmeta";
|
import { getMetaFromId } from "@/backend/metadata/getmeta";
|
||||||
import { decodeTMDBId } from "@/backend/metadata/tmdb";
|
import { decodeTMDBId } from "@/backend/metadata/tmdb";
|
||||||
import {
|
import {
|
||||||
@ -16,9 +19,6 @@ import { FloatingView } from "@/components/popout/FloatingView";
|
|||||||
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
||||||
import { useLoading } from "@/hooks/useLoading";
|
import { useLoading } from "@/hooks/useLoading";
|
||||||
import { useWatchedContext } from "@/state/watched";
|
import { useWatchedContext } from "@/state/watched";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
|
||||||
|
|
||||||
import { PopoutListEntry } from "./PopoutUtils";
|
import { PopoutListEntry } from "./PopoutUtils";
|
||||||
|
|
@ -1,13 +1,13 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
import { FloatingCardView } from "@/components/popout/FloatingCard";
|
import { FloatingCardView } from "@/components/popout/FloatingCard";
|
||||||
import { FloatingView } from "@/components/popout/FloatingView";
|
import { FloatingView } from "@/components/popout/FloatingView";
|
||||||
import { Slider } from "@/components/Slider";
|
import { Slider } from "@/components/Slider";
|
||||||
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
|
||||||
|
|
||||||
import { PopoutListEntry, PopoutSection } from "./PopoutUtils";
|
import { PopoutListEntry, PopoutSection } from "./PopoutUtils";
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
import { ReactNode, useEffect, useRef } from "react";
|
import { ReactNode, useEffect, useRef } from "react";
|
||||||
|
|
||||||
import { getPlayerState } from "@/video/state/cache";
|
import { getPlayerState } from "@/_oldvideo/state/cache";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
import { updateInterface } from "@/video/state/logic/interface";
|
import { updateInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
for: string;
|
for: string;
|
@ -1,13 +1,13 @@
|
|||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
|
|
||||||
|
import { useSyncPopouts } from "@/_oldvideo/components/hooks/useSyncPopouts";
|
||||||
|
import { EpisodeSelectionPopout } from "@/_oldvideo/components/popouts/EpisodeSelectionPopout";
|
||||||
|
import { SettingsPopout } from "@/_oldvideo/components/popouts/SettingsPopout";
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
import { PopoutFloatingCard } from "@/components/popout/FloatingCard";
|
import { PopoutFloatingCard } from "@/components/popout/FloatingCard";
|
||||||
import { FloatingContainer } from "@/components/popout/FloatingContainer";
|
import { FloatingContainer } from "@/components/popout/FloatingContainer";
|
||||||
import { useSyncPopouts } from "@/video/components/hooks/useSyncPopouts";
|
|
||||||
import { EpisodeSelectionPopout } from "@/video/components/popouts/EpisodeSelectionPopout";
|
|
||||||
import { SettingsPopout } from "@/video/components/popouts/SettingsPopout";
|
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
|
||||||
|
|
||||||
function ShowPopout(props: { popoutId: string | null; onClose: () => void }) {
|
function ShowPopout(props: { popoutId: string | null; onClose: () => void }) {
|
||||||
const popoutMap = {
|
const popoutMap = {
|
@ -1,11 +1,11 @@
|
|||||||
|
import { CaptionsSelectionAction } from "@/_oldvideo/components/actions/list-entries/CaptionsSelectionAction";
|
||||||
|
import { DownloadAction } from "@/_oldvideo/components/actions/list-entries/DownloadAction";
|
||||||
|
import { PlaybackSpeedSelectionAction } from "@/_oldvideo/components/actions/list-entries/PlaybackSpeedSelectionAction";
|
||||||
|
import { SourceSelectionAction } from "@/_oldvideo/components/actions/list-entries/SourceSelectionAction";
|
||||||
import { FloatingCardView } from "@/components/popout/FloatingCard";
|
import { FloatingCardView } from "@/components/popout/FloatingCard";
|
||||||
import { FloatingDragHandle } from "@/components/popout/FloatingDragHandle";
|
import { FloatingDragHandle } from "@/components/popout/FloatingDragHandle";
|
||||||
import { FloatingView } from "@/components/popout/FloatingView";
|
import { FloatingView } from "@/components/popout/FloatingView";
|
||||||
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
||||||
import { CaptionsSelectionAction } from "@/video/components/actions/list-entries/CaptionsSelectionAction";
|
|
||||||
import { DownloadAction } from "@/video/components/actions/list-entries/DownloadAction";
|
|
||||||
import { PlaybackSpeedSelectionAction } from "@/video/components/actions/list-entries/PlaybackSpeedSelectionAction";
|
|
||||||
import { SourceSelectionAction } from "@/video/components/actions/list-entries/SourceSelectionAction";
|
|
||||||
|
|
||||||
import { CaptionSelectionPopout } from "./CaptionSelectionPopout";
|
import { CaptionSelectionPopout } from "./CaptionSelectionPopout";
|
||||||
import { CaptionSettingsPopout } from "./CaptionSettingsPopout";
|
import { CaptionSettingsPopout } from "./CaptionSettingsPopout";
|
@ -1,6 +1,10 @@
|
|||||||
import { useMemo, useRef, useState } from "react";
|
import { useMemo, useRef, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { useVideoPlayerDescriptor } from "@/_oldvideo/state/hooks";
|
||||||
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
|
import { useMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
|
import { useSource } from "@/_oldvideo/state/logic/source";
|
||||||
import { MWEmbed, MWEmbedType } from "@/backend/helpers/embed";
|
import { MWEmbed, MWEmbedType } from "@/backend/helpers/embed";
|
||||||
import { MWProviderScrapeResult } from "@/backend/helpers/provider";
|
import { MWProviderScrapeResult } from "@/backend/helpers/provider";
|
||||||
import {
|
import {
|
||||||
@ -16,10 +20,6 @@ import { FloatingCardView } from "@/components/popout/FloatingCard";
|
|||||||
import { FloatingView } from "@/components/popout/FloatingView";
|
import { FloatingView } from "@/components/popout/FloatingView";
|
||||||
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
import { useFloatingRouter } from "@/hooks/useFloatingRouter";
|
||||||
import { useLoading } from "@/hooks/useLoading";
|
import { useLoading } from "@/hooks/useLoading";
|
||||||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
|
||||||
import { useMeta } from "@/video/state/logic/meta";
|
|
||||||
import { useSource } from "@/video/state/logic/source";
|
|
||||||
|
|
||||||
import { PopoutListEntry } from "./PopoutUtils";
|
import { PopoutListEntry } from "./PopoutUtils";
|
||||||
|
|
@ -1,7 +1,10 @@
|
|||||||
import { updateInterface } from "@/video/state/logic/interface";
|
import { updateInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
import { updateMeta } from "@/video/state/logic/meta";
|
import { updateMeta } from "@/_oldvideo/state/logic/meta";
|
||||||
import { updateProgress } from "@/video/state/logic/progress";
|
import { updateProgress } from "@/_oldvideo/state/logic/progress";
|
||||||
import { VideoPlayerMeta, VideoPlayerTimeFormat } from "@/video/state/types";
|
import {
|
||||||
|
VideoPlayerMeta,
|
||||||
|
VideoPlayerTimeFormat,
|
||||||
|
} from "@/_oldvideo/state/types";
|
||||||
|
|
||||||
import { getPlayerState } from "../cache";
|
import { getPlayerState } from "../cache";
|
||||||
import { VideoPlayerStateController } from "../providers/providerTypes";
|
import { VideoPlayerStateController } from "../providers/providerTypes";
|
@ -1,5 +1,12 @@
|
|||||||
import fscreen from "fscreen";
|
import fscreen from "fscreen";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getStoredVolume,
|
||||||
|
setStoredVolume,
|
||||||
|
} from "@/_oldvideo/components/hooks/volumeStore";
|
||||||
|
import { updateInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
import { updateSource } from "@/_oldvideo/state/logic/source";
|
||||||
|
import { resetStateForSource } from "@/_oldvideo/state/providers/helpers";
|
||||||
import { revokeCaptionBlob } from "@/backend/helpers/captions";
|
import { revokeCaptionBlob } from "@/backend/helpers/captions";
|
||||||
import {
|
import {
|
||||||
canChangeVolume,
|
canChangeVolume,
|
||||||
@ -7,13 +14,6 @@ import {
|
|||||||
canFullscreenAnyElement,
|
canFullscreenAnyElement,
|
||||||
canWebkitFullscreen,
|
canWebkitFullscreen,
|
||||||
} from "@/utils/detectFeatures";
|
} from "@/utils/detectFeatures";
|
||||||
import {
|
|
||||||
getStoredVolume,
|
|
||||||
setStoredVolume,
|
|
||||||
} from "@/video/components/hooks/volumeStore";
|
|
||||||
import { updateInterface } from "@/video/state/logic/interface";
|
|
||||||
import { updateSource } from "@/video/state/logic/source";
|
|
||||||
import { resetStateForSource } from "@/video/state/providers/helpers";
|
|
||||||
|
|
||||||
import { VideoPlayerStateProvider } from "./providerTypes";
|
import { VideoPlayerStateProvider } from "./providerTypes";
|
||||||
import { SettingsStore } from "../../../state/settings/store";
|
import { SettingsStore } from "../../../state/settings/store";
|
@ -1,8 +1,8 @@
|
|||||||
import { resetForSource } from "@/video/state/init";
|
import { resetForSource } from "@/_oldvideo/state/init";
|
||||||
import { updateMediaPlaying } from "@/video/state/logic/mediaplaying";
|
import { updateMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
import { updateMisc } from "@/video/state/logic/misc";
|
import { updateMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
import { updateProgress } from "@/video/state/logic/progress";
|
import { updateProgress } from "@/_oldvideo/state/logic/progress";
|
||||||
import { VideoPlayerState } from "@/video/state/types";
|
import { VideoPlayerState } from "@/_oldvideo/state/types";
|
||||||
|
|
||||||
export function resetStateForSource(descriptor: string, s: VideoPlayerState) {
|
export function resetStateForSource(descriptor: string, s: VideoPlayerState) {
|
||||||
const state = s;
|
const state = s;
|
@ -1,4 +1,4 @@
|
|||||||
import { updateMisc } from "@/video/state/logic/misc";
|
import { updateMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
|
|
||||||
import { VideoPlayerStateProvider } from "./providerTypes";
|
import { VideoPlayerStateProvider } from "./providerTypes";
|
||||||
import { getPlayerState } from "../cache";
|
import { getPlayerState } from "../cache";
|
@ -1,6 +1,15 @@
|
|||||||
import fscreen from "fscreen";
|
import fscreen from "fscreen";
|
||||||
import Hls from "hls.js";
|
import Hls from "hls.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getStoredVolume,
|
||||||
|
setStoredVolume,
|
||||||
|
} from "@/_oldvideo/components/hooks/volumeStore";
|
||||||
|
import { updateError } from "@/_oldvideo/state/logic/error";
|
||||||
|
import { updateInterface } from "@/_oldvideo/state/logic/interface";
|
||||||
|
import { updateMisc } from "@/_oldvideo/state/logic/misc";
|
||||||
|
import { updateSource } from "@/_oldvideo/state/logic/source";
|
||||||
|
import { resetStateForSource } from "@/_oldvideo/state/providers/helpers";
|
||||||
import { revokeCaptionBlob } from "@/backend/helpers/captions";
|
import { revokeCaptionBlob } from "@/backend/helpers/captions";
|
||||||
import { MWStreamType } from "@/backend/helpers/streams";
|
import { MWStreamType } from "@/backend/helpers/streams";
|
||||||
import {
|
import {
|
||||||
@ -11,15 +20,6 @@ import {
|
|||||||
canWebkitFullscreen,
|
canWebkitFullscreen,
|
||||||
canWebkitPictureInPicture,
|
canWebkitPictureInPicture,
|
||||||
} from "@/utils/detectFeatures";
|
} from "@/utils/detectFeatures";
|
||||||
import {
|
|
||||||
getStoredVolume,
|
|
||||||
setStoredVolume,
|
|
||||||
} from "@/video/components/hooks/volumeStore";
|
|
||||||
import { updateError } from "@/video/state/logic/error";
|
|
||||||
import { updateInterface } from "@/video/state/logic/interface";
|
|
||||||
import { updateMisc } from "@/video/state/logic/misc";
|
|
||||||
import { updateSource } from "@/video/state/logic/source";
|
|
||||||
import { resetStateForSource } from "@/video/state/providers/helpers";
|
|
||||||
|
|
||||||
import { VideoPlayerStateProvider } from "./providerTypes";
|
import { VideoPlayerStateProvider } from "./providerTypes";
|
||||||
import { handleBuffered } from "./utils";
|
import { handleBuffered } from "./utils";
|
2
src/components/player/Player.tsx
Normal file
2
src/components/player/Player.tsx
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from "./atoms";
|
||||||
|
export * from "./base/Container";
|
16
src/components/player/README.md
Normal file
16
src/components/player/README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Video player component
|
||||||
|
|
||||||
|
Video player is quite a complex component, so here is a rundown of all the parts
|
||||||
|
|
||||||
|
# Composable parts
|
||||||
|
These parts can be used to build any shape of a video player.
|
||||||
|
- `/atoms`- any ui element that controls the player. (Seekbar, Pause button, quality selection, etc)
|
||||||
|
- `/base` - base components that are used to build a player. Like the main container
|
||||||
|
|
||||||
|
# internal parts
|
||||||
|
These parts are internally used, they aren't exported. Do not use them outside of player internals.
|
||||||
|
- `/display` - display interface, abstraction on how to actually play the content (e.g Video element, HLS player, Standard video element, etc)
|
||||||
|
- `/internals` - Internal components that are always rendered on every player.
|
||||||
|
- `/utils` - miscellaneous logic
|
||||||
|
- `/hooks` - hooks only used for video player
|
||||||
|
- `~/src/stores/player` - state for the video player. Should only be used by internal parts
|
1
src/components/player/atoms/index.ts
Normal file
1
src/components/player/atoms/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./pause";
|
3
src/components/player/atoms/pause.tsx
Normal file
3
src/components/player/atoms/pause.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function Pause() {
|
||||||
|
return <button type="button" />;
|
||||||
|
}
|
16
src/components/player/base/Container.tsx
Normal file
16
src/components/player/base/Container.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
import { VideoContainer } from "@/components/player/internals/VideoContainer";
|
||||||
|
|
||||||
|
export interface PlayerProps {
|
||||||
|
children?: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Container(props: PlayerProps) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<VideoContainer />
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
0
src/components/player/display/base.ts
Normal file
0
src/components/player/display/base.ts
Normal file
13
src/components/player/display/displayInterface.ts
Normal file
13
src/components/player/display/displayInterface.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Source } from "@/components/player/hooks/usePlayer";
|
||||||
|
import { Listener } from "@/utils/events";
|
||||||
|
|
||||||
|
export type DisplayInterfaceEvents = {
|
||||||
|
play: void;
|
||||||
|
pause: void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface DisplayInterface extends Listener<DisplayInterfaceEvents> {
|
||||||
|
play(): void;
|
||||||
|
pause(): void;
|
||||||
|
load(source: Source): void;
|
||||||
|
}
|
20
src/components/player/hooks/usePlayer.ts
Normal file
20
src/components/player/hooks/usePlayer.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { MWStreamType } from "@/backend/helpers/streams";
|
||||||
|
import { playerStatus } from "@/stores/player/slices/source";
|
||||||
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
|
export interface Source {
|
||||||
|
url: string;
|
||||||
|
type: MWStreamType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function usePlayer() {
|
||||||
|
const setStatus = usePlayerStore((s) => s.setStatus);
|
||||||
|
const setSource = usePlayerStore((s) => s.setSource);
|
||||||
|
|
||||||
|
return {
|
||||||
|
playMedia(source: Source) {
|
||||||
|
setSource(source.url, source.type);
|
||||||
|
setStatus(playerStatus.PLAYING);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
1
src/components/player/index.tsx
Normal file
1
src/components/player/index.tsx
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * as Player from "./Player";
|
36
src/components/player/internals/VideoContainer.tsx
Normal file
36
src/components/player/internals/VideoContainer.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { RefObject, useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
import { MWStreamType } from "@/backend/helpers/streams";
|
||||||
|
import { SourceSliceSource } from "@/stores/player/slices/source";
|
||||||
|
import { AllSlices } from "@/stores/player/slices/types";
|
||||||
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
|
// should this video container show right now?
|
||||||
|
function useShouldShow(source: SourceSliceSource | null): boolean {
|
||||||
|
if (!source) return false;
|
||||||
|
if (source.type !== MWStreamType.MP4) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make video element up to par with the state
|
||||||
|
function useRestoreVideo(
|
||||||
|
videoRef: RefObject<HTMLVideoElement>,
|
||||||
|
player: AllSlices
|
||||||
|
) {
|
||||||
|
useEffect(() => {
|
||||||
|
const el = videoRef.current;
|
||||||
|
const src = player.source?.url ?? "";
|
||||||
|
if (!el) return;
|
||||||
|
if (el.src !== src) el.src = src;
|
||||||
|
}, [player.source?.url, videoRef]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VideoContainer() {
|
||||||
|
const videoEl = useRef<HTMLVideoElement>(null);
|
||||||
|
const player = usePlayerStore();
|
||||||
|
useRestoreVideo(videoEl, player);
|
||||||
|
const show = useShouldShow(player.source);
|
||||||
|
|
||||||
|
if (!show) return null;
|
||||||
|
return <video autoPlay ref={videoEl} />;
|
||||||
|
}
|
@ -2,10 +2,10 @@ import { animated, easings, useSpringValue } from "@react-spring/web";
|
|||||||
import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
|
import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { PopoutSection } from "@/_oldvideo/components/popouts/PopoutUtils";
|
||||||
import { FloatingCardAnchorPosition } from "@/components/popout/positions/FloatingCardAnchorPosition";
|
import { FloatingCardAnchorPosition } from "@/components/popout/positions/FloatingCardAnchorPosition";
|
||||||
import { FloatingCardMobilePosition } from "@/components/popout/positions/FloatingCardMobilePosition";
|
import { FloatingCardMobilePosition } from "@/components/popout/positions/FloatingCardMobilePosition";
|
||||||
import { useIsMobile } from "@/hooks/useIsMobile";
|
import { useIsMobile } from "@/hooks/useIsMobile";
|
||||||
import { PopoutSection } from "@/video/components/popouts/PopoutUtils";
|
|
||||||
|
|
||||||
import { FloatingDragHandle, MobilePopoutSpacer } from "./FloatingDragHandle";
|
import { FloatingDragHandle, MobilePopoutSpacer } from "./FloatingDragHandle";
|
||||||
import { Icon, Icons } from "../Icon";
|
import { Icon, Icons } from "../Icon";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
import { useControls } from "@/video/state/logic/controls";
|
import { useControls } from "@/_oldvideo/state/logic/controls";
|
||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
import { useMediaPlaying } from "@/_oldvideo/state/logic/mediaplaying";
|
||||||
|
|
||||||
export function useVolumeControl(descriptor: string) {
|
export function useVolumeControl(descriptor: string) {
|
||||||
const [storedVolume, setStoredVolume] = useState(1);
|
const [storedVolume, setStoredVolume] = useState(1);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import "core-js/stable";
|
import "core-js/stable";
|
||||||
import React, { Suspense } from "react";
|
import React, { Suspense } from "react";
|
||||||
|
import type { ReactNode } from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import { BrowserRouter, HashRouter } from "react-router-dom";
|
import { BrowserRouter, HashRouter } from "react-router-dom";
|
||||||
import type { ReactNode } from "react-router-dom/node_modules/@types/react/index";
|
|
||||||
import { registerSW } from "virtual:pwa-register";
|
import { registerSW } from "virtual:pwa-register";
|
||||||
|
|
||||||
import { ErrorBoundary } from "@/components/layout/ErrorBoundary";
|
import { ErrorBoundary } from "@/components/layout/ErrorBoundary";
|
||||||
|
9
src/pages/PlayerView.tsx
Normal file
9
src/pages/PlayerView.tsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { Player } from "@/components/player";
|
||||||
|
|
||||||
|
export function PlayerView() {
|
||||||
|
return (
|
||||||
|
<Player.Container>
|
||||||
|
<Player.Pause />
|
||||||
|
</Player.Container>
|
||||||
|
);
|
||||||
|
}
|
@ -1,113 +1,18 @@
|
|||||||
import { useCallback, useState } from "react";
|
import { useEffect } from "react";
|
||||||
import { Helmet } from "react-helmet";
|
|
||||||
|
|
||||||
import { MWStreamQuality, MWStreamType } from "@/backend/helpers/streams";
|
import { MWStreamType } from "@/backend/helpers/streams";
|
||||||
import { DetailedMeta } from "@/backend/metadata/getmeta";
|
import { usePlayer } from "@/components/player/hooks/usePlayer";
|
||||||
import { MWMediaType } from "@/backend/metadata/types/mw";
|
import { PlayerView } from "@/pages/PlayerView";
|
||||||
import { Button } from "@/components/Button";
|
|
||||||
import { Dropdown } from "@/components/Dropdown";
|
|
||||||
import { Navigation } from "@/components/layout/Navigation";
|
|
||||||
import { ThinContainer } from "@/components/layout/ThinContainer";
|
|
||||||
import { MetaController } from "@/video/components/controllers/MetaController";
|
|
||||||
import { SourceController } from "@/video/components/controllers/SourceController";
|
|
||||||
import { VideoPlayer } from "@/video/components/VideoPlayer";
|
|
||||||
|
|
||||||
interface VideoData {
|
|
||||||
streamUrl: string;
|
|
||||||
type: MWStreamType;
|
|
||||||
}
|
|
||||||
|
|
||||||
const testData: VideoData = {
|
|
||||||
streamUrl:
|
|
||||||
"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
|
||||||
type: MWStreamType.MP4,
|
|
||||||
};
|
|
||||||
const testMeta: DetailedMeta = {
|
|
||||||
imdbId: "",
|
|
||||||
tmdbId: "",
|
|
||||||
meta: {
|
|
||||||
id: "hello-world",
|
|
||||||
title: "Big Buck Bunny",
|
|
||||||
type: MWMediaType.MOVIE,
|
|
||||||
seasons: undefined,
|
|
||||||
year: "2000",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function VideoTesterView() {
|
export default function VideoTesterView() {
|
||||||
const [video, setVideo] = useState<VideoData | null>(null);
|
const player = usePlayer();
|
||||||
const [videoType, setVideoType] = useState<MWStreamType>(MWStreamType.MP4);
|
|
||||||
const [url, setUrl] = useState("");
|
|
||||||
|
|
||||||
const playVideo = useCallback(
|
useEffect(() => {
|
||||||
(streamUrl: string) => {
|
player.playMedia({
|
||||||
setVideo({
|
type: MWStreamType.MP4,
|
||||||
streamUrl,
|
url: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
||||||
type: videoType,
|
});
|
||||||
});
|
});
|
||||||
},
|
|
||||||
[videoType]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (video) {
|
return <PlayerView />;
|
||||||
return (
|
|
||||||
<div className="fixed left-0 top-0 h-[100dvh] w-screen">
|
|
||||||
<Helmet>
|
|
||||||
<html data-full="true" />
|
|
||||||
</Helmet>
|
|
||||||
<VideoPlayer includeSafeArea autoPlay onGoBack={() => setVideo(null)}>
|
|
||||||
<MetaController
|
|
||||||
data={{
|
|
||||||
captions: [],
|
|
||||||
meta: testMeta,
|
|
||||||
}}
|
|
||||||
linkedCaptions={[]}
|
|
||||||
/>
|
|
||||||
<SourceController
|
|
||||||
source={video.streamUrl}
|
|
||||||
type={videoType}
|
|
||||||
quality={MWStreamQuality.QUNKNOWN}
|
|
||||||
captions={[]}
|
|
||||||
/>
|
|
||||||
</VideoPlayer>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="py-64">
|
|
||||||
<Navigation />
|
|
||||||
<ThinContainer classNames="flex items-start flex-col space-y-4">
|
|
||||||
<div className="w-48">
|
|
||||||
<Dropdown
|
|
||||||
options={[
|
|
||||||
{ id: MWStreamType.MP4, name: "Mp4" },
|
|
||||||
{ id: MWStreamType.HLS, name: "hls/m3u8" },
|
|
||||||
]}
|
|
||||||
selectedItem={{ id: videoType, name: videoType }}
|
|
||||||
setSelectedItem={(a) => setVideoType(a.id as MWStreamType)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="mb-4 flex gap-4">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="stream url here..."
|
|
||||||
value={url}
|
|
||||||
onChange={(e) => setUrl(e.target.value)}
|
|
||||||
/>
|
|
||||||
<Button onClick={() => playVideo(url)}>Play video</Button>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
onClick={() =>
|
|
||||||
setVideo({
|
|
||||||
streamUrl: testData.streamUrl,
|
|
||||||
type: testData.type,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Play default video
|
|
||||||
</Button>
|
|
||||||
</ThinContainer>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Helmet } from "react-helmet";
|
import { Helmet } from "react-helmet";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { VideoPlayerHeader } from "@/_oldvideo/components/parts/VideoPlayerHeader";
|
||||||
import { ErrorMessage } from "@/components/layout/ErrorBoundary";
|
import { ErrorMessage } from "@/components/layout/ErrorBoundary";
|
||||||
import { useGoBack } from "@/hooks/useGoBack";
|
import { useGoBack } from "@/hooks/useGoBack";
|
||||||
import { VideoPlayerHeader } from "@/video/components/parts/VideoPlayerHeader";
|
|
||||||
|
|
||||||
export function MediaFetchErrorView() {
|
export function MediaFetchErrorView() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user