mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
Time format
This commit is contained in:
parent
3decc9190c
commit
84b8a67cea
8 changed files with 65 additions and 5 deletions
|
@ -1,6 +1,7 @@
|
|||
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
|
||||
import { useMediaPlaying } from "@/video/state/logic/mediaplaying";
|
||||
import { useProgress } from "@/video/state/logic/progress";
|
||||
import { useInterface } from "@/video/state/logic/interface";
|
||||
|
||||
function durationExceedsHour(secs: number): boolean {
|
||||
return secs > 60 * 60;
|
||||
|
@ -37,6 +38,7 @@ export function TimeAction(props: Props) {
|
|||
const descriptor = useVideoPlayerDescriptor();
|
||||
const videoTime = useProgress(descriptor);
|
||||
const mediaPlaying = useMediaPlaying(descriptor);
|
||||
const { timeFormat, setTimeFormat } = useInterface(descriptor);
|
||||
|
||||
const hasHours = durationExceedsHour(videoTime.duration);
|
||||
const time = formatSeconds(
|
||||
|
@ -45,11 +47,47 @@ export function TimeAction(props: Props) {
|
|||
);
|
||||
const duration = formatSeconds(videoTime.duration, hasHours);
|
||||
|
||||
const timeLeft = formatSeconds(
|
||||
(videoTime.duration - videoTime.time) / mediaPlaying.playbackSpeed
|
||||
);
|
||||
|
||||
const timeFinished = new Date(
|
||||
new Date().getTime() +
|
||||
(videoTime.duration * 1000) / mediaPlaying.playbackSpeed
|
||||
).toLocaleTimeString("en-US", {
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
hour12: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={props.className}>
|
||||
<p className="select-none text-white">
|
||||
{time} {props.noDuration ? "" : `/ ${duration}`}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={[
|
||||
"group pointer-events-auto translate-x-[-16px] text-white transition-transform duration-100 active:scale-110",
|
||||
].join(" ")}
|
||||
onClick={() => {
|
||||
setTimeFormat(timeFormat === 0 ? 1 : 0);
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={[
|
||||
"flex items-center justify-center rounded-full bg-denim-600 bg-opacity-0 p-2 transition-colors duration-100 group-hover:bg-opacity-50 group-active:bg-denim-500 group-active:bg-opacity-100 sm:px-4",
|
||||
].join(" ")}
|
||||
>
|
||||
<div className={props.className}>
|
||||
<p className="select-none text-white">
|
||||
{/* {time} {props.noDuration ? "" : `/ ${duration}`} */}
|
||||
{timeFormat === 0
|
||||
? `${time} ${props.noDuration ? "" : `/ ${duration}`}`
|
||||
: `${timeLeft} left${
|
||||
videoTime.time === videoTime.duration
|
||||
? ""
|
||||
: ` - finish at ${timeFinished}`
|
||||
} `}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ function initPlayer(): VideoPlayerState {
|
|||
isFocused: false,
|
||||
leftControlHovering: false,
|
||||
popoutBounds: null,
|
||||
timeFormat: 0,
|
||||
},
|
||||
|
||||
mediaPlaying: {
|
||||
|
|
|
@ -15,6 +15,7 @@ export type ControlMethods = {
|
|||
setDraggingTime(num: number): void;
|
||||
togglePictureInPicture(): void;
|
||||
setPlaybackSpeed(num: number): void;
|
||||
setTimeFormat(num: 0 | 1): void;
|
||||
};
|
||||
|
||||
export function useControls(
|
||||
|
@ -110,5 +111,9 @@ export function useControls(
|
|||
state.stateProvider?.setPlaybackSpeed(num);
|
||||
updateInterface(descriptor, state);
|
||||
},
|
||||
setTimeFormat(format) {
|
||||
state.interface.timeFormat = format;
|
||||
updateInterface(descriptor, state);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ export type VideoInterfaceEvent = {
|
|||
isFocused: boolean;
|
||||
isFullscreen: boolean;
|
||||
popoutBounds: null | DOMRect;
|
||||
timeFormat: 0 | 1 | 2;
|
||||
setTimeFormat(timeFormat: 0 | 1 | 2): void;
|
||||
};
|
||||
|
||||
function getInterfaceFromState(state: VideoPlayerState): VideoInterfaceEvent {
|
||||
|
@ -18,6 +20,10 @@ function getInterfaceFromState(state: VideoPlayerState): VideoInterfaceEvent {
|
|||
isFocused: state.interface.isFocused,
|
||||
isFullscreen: state.interface.isFullscreen,
|
||||
popoutBounds: state.interface.popoutBounds,
|
||||
timeFormat: state.interface.timeFormat,
|
||||
setTimeFormat(timeFormat: 0 | 1 | 2) {
|
||||
state.stateProvider?.setTimeFormat(timeFormat);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -173,6 +173,10 @@ export function createCastingStateProvider(
|
|||
updateSource(descriptor, state);
|
||||
}
|
||||
},
|
||||
setTimeFormat(format) {
|
||||
state.interface.timeFormat = format;
|
||||
updateInterface(descriptor, state);
|
||||
},
|
||||
providerStart() {
|
||||
this.setVolume(getStoredVolume());
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ export type VideoPlayerStateController = {
|
|||
getId(): string;
|
||||
togglePictureInPicture(): void;
|
||||
setPlaybackSpeed(num: number): void;
|
||||
setTimeFormat(format: 0 | 1 | 2): void;
|
||||
};
|
||||
|
||||
export type VideoPlayerStateProvider = VideoPlayerStateController & {
|
||||
|
|
|
@ -133,6 +133,10 @@ export function createVideoStateProvider(
|
|||
// update localstorage
|
||||
setStoredVolume(volume);
|
||||
},
|
||||
setTimeFormat(num) {
|
||||
state.interface.timeFormat = num;
|
||||
updateInterface(descriptor, state);
|
||||
},
|
||||
setSource(source) {
|
||||
if (!source) {
|
||||
resetStateForSource(descriptor, state);
|
||||
|
|
|
@ -30,6 +30,7 @@ export type VideoPlayerState = {
|
|||
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
|
||||
popoutBounds: null | DOMRect; // bounding box of current popout
|
||||
timeFormat: 0 | 1 | 2; // Time format of the video player
|
||||
};
|
||||
|
||||
// state related to the playing state of the media
|
||||
|
|
Loading…
Reference in a new issue