mirror of
https://github.com/movie-web/movie-web.git
synced 2024-12-28 02:51:49 +01:00
Reviews
This commit is contained in:
parent
c330112dbc
commit
41fd23cf20
@ -3,6 +3,9 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
||||||
import { useProgress } from "@/video/state/logic/progress";
|
import { useProgress } from "@/video/state/logic/progress";
|
||||||
import { useInterface } from "@/video/state/logic/interface";
|
import { useInterface } from "@/video/state/logic/interface";
|
||||||
|
import { VideoPlayerTimeFormat } from "@/video/state/types";
|
||||||
|
import { useIsMobile } from "@/hooks/useIsMobile";
|
||||||
|
import { useControls } from "@/video/state/logic/controls";
|
||||||
|
|
||||||
function durationExceedsHour(secs: number): boolean {
|
function durationExceedsHour(secs: number): boolean {
|
||||||
return secs > 60 * 60;
|
return secs > 60 * 60;
|
||||||
@ -40,19 +43,20 @@ export function TimeAction(props: Props) {
|
|||||||
const videoTime = useProgress(descriptor);
|
const videoTime = useProgress(descriptor);
|
||||||
const mediaPlaying = useMediaPlaying(descriptor);
|
const mediaPlaying = useMediaPlaying(descriptor);
|
||||||
const { timeFormat, setTimeFormat } = useInterface(descriptor);
|
const { timeFormat, setTimeFormat } = useInterface(descriptor);
|
||||||
|
const { isMobile } = useIsMobile();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const hasHours = durationExceedsHour(videoTime.duration);
|
const hasHours = durationExceedsHour(videoTime.duration);
|
||||||
const time = formatSeconds(
|
|
||||||
|
const currentTime = formatSeconds(
|
||||||
mediaPlaying.isDragSeeking ? videoTime.draggingTime : videoTime.time,
|
mediaPlaying.isDragSeeking ? videoTime.draggingTime : videoTime.time,
|
||||||
hasHours
|
hasHours
|
||||||
);
|
);
|
||||||
const duration = formatSeconds(videoTime.duration, hasHours);
|
const duration = formatSeconds(videoTime.duration, hasHours);
|
||||||
|
|
||||||
const timeLeft = formatSeconds(
|
const timeLeft = formatSeconds(
|
||||||
(videoTime.duration - videoTime.time) / mediaPlaying.playbackSpeed
|
(videoTime.duration - videoTime.time) / mediaPlaying.playbackSpeed,
|
||||||
|
hasHours
|
||||||
);
|
);
|
||||||
|
|
||||||
const timeFinished = new Date(
|
const timeFinished = new Date(
|
||||||
new Date().getTime() +
|
new Date().getTime() +
|
||||||
(videoTime.duration * 1000) / mediaPlaying.playbackSpeed
|
(videoTime.duration * 1000) / mediaPlaying.playbackSpeed
|
||||||
@ -61,15 +65,38 @@ export function TimeAction(props: Props) {
|
|||||||
minute: "numeric",
|
minute: "numeric",
|
||||||
hour12: true,
|
hour12: true,
|
||||||
});
|
});
|
||||||
|
const formattedTimeFinished = ` - ${t("videoPlayer.finishAt", {
|
||||||
|
timeFinished,
|
||||||
|
})}`;
|
||||||
|
|
||||||
|
let formattedTime: string;
|
||||||
|
|
||||||
|
if (timeFormat === VideoPlayerTimeFormat.REGULAR) {
|
||||||
|
formattedTime = `${currentTime} ${props.noDuration ? "" : `/ ${duration}`}`;
|
||||||
|
} else if (timeFormat === VideoPlayerTimeFormat.REMAINING) {
|
||||||
|
formattedTime = `${t("videoPlayer.timeLeft", {
|
||||||
|
timeLeft,
|
||||||
|
})}${
|
||||||
|
videoTime.time === videoTime.duration || isMobile
|
||||||
|
? ""
|
||||||
|
: formattedTimeFinished
|
||||||
|
} `;
|
||||||
|
} else {
|
||||||
|
formattedTime = "";
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={[
|
className={[
|
||||||
"group pointer-events-auto translate-x-[-16px] text-white transition-transform duration-100 active:scale-110",
|
"group pointer-events-auto text-white transition-transform duration-100 active:scale-110",
|
||||||
].join(" ")}
|
].join(" ")}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setTimeFormat(timeFormat === 0 ? 1 : 0);
|
setTimeFormat(
|
||||||
|
timeFormat === VideoPlayerTimeFormat.REGULAR
|
||||||
|
? VideoPlayerTimeFormat.REMAINING
|
||||||
|
: VideoPlayerTimeFormat.REGULAR
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -78,20 +105,7 @@ export function TimeAction(props: Props) {
|
|||||||
].join(" ")}
|
].join(" ")}
|
||||||
>
|
>
|
||||||
<div className={props.className}>
|
<div className={props.className}>
|
||||||
<p className="select-none text-white">
|
<p className="select-none text-white">{formattedTime}</p>
|
||||||
{/* {time} {props.noDuration ? "" : `/ ${duration}`} */}
|
|
||||||
{timeFormat === 0
|
|
||||||
? `${time} ${props.noDuration ? "" : `/ ${duration}`}`
|
|
||||||
: `${t("videoPlayer.timeLeft", {
|
|
||||||
timeLeft,
|
|
||||||
})}${
|
|
||||||
videoTime.time === videoTime.duration
|
|
||||||
? ""
|
|
||||||
: ` - ${t("videoPlayer.finishAt", {
|
|
||||||
timeFinished,
|
|
||||||
})}`
|
|
||||||
} `}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { updateInterface } from "@/video/state/logic/interface";
|
import { updateInterface } from "@/video/state/logic/interface";
|
||||||
import { updateMeta } from "@/video/state/logic/meta";
|
import { updateMeta } from "@/video/state/logic/meta";
|
||||||
import { updateProgress } from "@/video/state/logic/progress";
|
import { updateProgress } from "@/video/state/logic/progress";
|
||||||
import { VideoPlayerMeta } from "@/video/state/types";
|
import { VideoPlayerMeta, VideoPlayerTimeFormat } from "@/video/state/types";
|
||||||
import { getPlayerState } from "../cache";
|
import { getPlayerState } from "../cache";
|
||||||
import { VideoPlayerStateController } from "../providers/providerTypes";
|
import { VideoPlayerStateController } from "../providers/providerTypes";
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ export type ControlMethods = {
|
|||||||
setDraggingTime(num: number): void;
|
setDraggingTime(num: number): void;
|
||||||
togglePictureInPicture(): void;
|
togglePictureInPicture(): void;
|
||||||
setPlaybackSpeed(num: number): void;
|
setPlaybackSpeed(num: number): void;
|
||||||
setTimeFormat(num: 0 | 1): void;
|
setTimeFormat(num: VideoPlayerTimeFormat): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useControls(
|
export function useControls(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { getPlayerState } from "../cache";
|
import { getPlayerState } from "../cache";
|
||||||
import { listenEvent, sendEvent, unlistenEvent } from "../events";
|
import { listenEvent, sendEvent, unlistenEvent } from "../events";
|
||||||
import { VideoPlayerState } from "../types";
|
import { VideoPlayerState, VideoPlayerTimeFormat } from "../types";
|
||||||
|
|
||||||
export type VideoInterfaceEvent = {
|
export type VideoInterfaceEvent = {
|
||||||
popout: string | null;
|
popout: string | null;
|
||||||
@ -9,8 +9,8 @@ export type VideoInterfaceEvent = {
|
|||||||
isFocused: boolean;
|
isFocused: boolean;
|
||||||
isFullscreen: boolean;
|
isFullscreen: boolean;
|
||||||
popoutBounds: null | DOMRect;
|
popoutBounds: null | DOMRect;
|
||||||
timeFormat: 0 | 1 | 2;
|
timeFormat: VideoPlayerTimeFormat;
|
||||||
setTimeFormat(timeFormat: 0 | 1 | 2): void;
|
setTimeFormat(timeFormat: VideoPlayerTimeFormat): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getInterfaceFromState(state: VideoPlayerState): VideoInterfaceEvent {
|
function getInterfaceFromState(state: VideoPlayerState): VideoInterfaceEvent {
|
||||||
@ -21,7 +21,7 @@ function getInterfaceFromState(state: VideoPlayerState): VideoInterfaceEvent {
|
|||||||
isFullscreen: state.interface.isFullscreen,
|
isFullscreen: state.interface.isFullscreen,
|
||||||
popoutBounds: state.interface.popoutBounds,
|
popoutBounds: state.interface.popoutBounds,
|
||||||
timeFormat: state.interface.timeFormat,
|
timeFormat: state.interface.timeFormat,
|
||||||
setTimeFormat(timeFormat: 0 | 1 | 2) {
|
setTimeFormat(timeFormat: VideoPlayerTimeFormat) {
|
||||||
state.stateProvider?.setTimeFormat(timeFormat);
|
state.stateProvider?.setTimeFormat(timeFormat);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { MWStreamQuality, MWStreamType } from "@/backend/helpers/streams";
|
import { MWStreamQuality, MWStreamType } from "@/backend/helpers/streams";
|
||||||
|
import { VideoPlayerTimeFormat } from "@/video/state/types";
|
||||||
|
|
||||||
type VideoPlayerSource = {
|
type VideoPlayerSource = {
|
||||||
source: string;
|
source: string;
|
||||||
@ -23,7 +24,7 @@ export type VideoPlayerStateController = {
|
|||||||
getId(): string;
|
getId(): string;
|
||||||
togglePictureInPicture(): void;
|
togglePictureInPicture(): void;
|
||||||
setPlaybackSpeed(num: number): void;
|
setPlaybackSpeed(num: number): void;
|
||||||
setTimeFormat(format: 0 | 1 | 2): void;
|
setTimeFormat(timeFormat: VideoPlayerTimeFormat): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type VideoPlayerStateProvider = VideoPlayerStateController & {
|
export type VideoPlayerStateProvider = VideoPlayerStateController & {
|
||||||
|
@ -22,6 +22,11 @@ export type VideoPlayerMeta = {
|
|||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export enum VideoPlayerTimeFormat {
|
||||||
|
REGULAR = 0,
|
||||||
|
REMAINING = 1,
|
||||||
|
}
|
||||||
|
|
||||||
export type VideoPlayerState = {
|
export type VideoPlayerState = {
|
||||||
// state related to the user interface
|
// state related to the user interface
|
||||||
interface: {
|
interface: {
|
||||||
@ -30,7 +35,7 @@ export type VideoPlayerState = {
|
|||||||
isFocused: boolean; // is the video player the users focus? (shortcuts only works when its focused)
|
isFocused: boolean; // is the video player the users focus? (shortcuts only works when its focused)
|
||||||
leftControlHovering: boolean; // is the cursor hovered over the left side of player controls
|
leftControlHovering: boolean; // is the cursor hovered over the left side of player controls
|
||||||
popoutBounds: null | DOMRect; // bounding box of current popout
|
popoutBounds: null | DOMRect; // bounding box of current popout
|
||||||
timeFormat: 0 | 1 | 2; // Time format of the video player
|
timeFormat: VideoPlayerTimeFormat; // Time format of the video player
|
||||||
};
|
};
|
||||||
|
|
||||||
// state related to the playing state of the media
|
// state related to the playing state of the media
|
||||||
|
Loading…
Reference in New Issue
Block a user