Skip to content

Commit

Permalink
Merge pull request #450 from AppQuality/integrate-shortcut-tooltip
Browse files Browse the repository at this point in the history
Integrate-shortcut-tooltip
  • Loading branch information
cannarocks authored Nov 28, 2024
2 parents 22445b3 + d66c2db commit 86e5243
Show file tree
Hide file tree
Showing 13 changed files with 274 additions and 54 deletions.
5 changes: 5 additions & 0 deletions src/assets/icons/arrow-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/arrow-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/stories/player/_types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export interface PlayerArgs extends HTMLAttributes<HTMLVideoElement> {
export interface PlayerI18n {
beforeHighlight?: string;
onHighlight?: string;
playpause?: string;
mute?: string;
observations?: string;
forward?: string;
backward?: string;
}

export interface IBookmark {
Expand Down
3 changes: 3 additions & 0 deletions src/stories/player/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Container } from "./parts/container";
import { Controls } from "./parts/controls";
import { FloatingControls } from "./parts/floatingControls";
import { VideoSpinner } from "./parts/spinner";
import { PlayerShortCut } from "./shortcuts";

/**
* The Player is a styled media tag with custom controls
Expand Down Expand Up @@ -101,4 +102,6 @@ const PlayerProvider = (props: PropsWithChildren<PlayerArgs>) => (

PlayerProvider.Core = PlayerCore;

PlayerProvider.Shortcut = PlayerShortCut;

export { Player, PlayerProvider, useVideoContext };
9 changes: 7 additions & 2 deletions src/stories/player/parts/audioButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useVideoContext } from "@appquality/stream-player";
import { useEffect, useState } from "react";
import { ReactComponent as MutedIcon } from "../../../assets/icons/volume-muted-fill.svg";
import { ReactComponent as UnMutedIcon } from "../../../assets/icons/volume-unmuted-fill.svg";
import { PlayerI18n } from "../_types";
import { ControlButton } from "./controlButton";

interface VideowithAudio extends HTMLVideoElement {
Expand All @@ -10,7 +11,7 @@ interface VideowithAudio extends HTMLVideoElement {
audioTracks?: any[];
}

export const AudioButton = () => {
export const AudioButton = ({ i18n }: { i18n?: PlayerI18n }) => {
const [hasAudio, setHasAudio] = useState<boolean>(false);
const { isMuted, setMuted, context } = useVideoContext();

Expand All @@ -20,7 +21,7 @@ export const AudioButton = () => {
if (!video) {
return false;
}

const videohasAudio =
video.mozHasAudio ||
Boolean(video.webkitAudioDecodedByteCount) ||
Expand Down Expand Up @@ -52,6 +53,10 @@ export const AudioButton = () => {
setMuted(!player.ref.current.volume);
}
}}
tooltip={{
description: i18n?.mute || "Mute",
type: "mute",
}}
>
{isMuted || !hasAudio ? <MutedIcon /> : <UnMutedIcon />}
</ControlButton>
Expand Down
32 changes: 31 additions & 1 deletion src/stories/player/parts/controlButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
import { ComponentProps } from "react";
import styled from "styled-components";
import { IconButton } from "../../buttons/icon-button";
import { Tooltip } from "../../tooltip";
import { PlayerShortCut } from "../shortcuts";

export const ControlButton = styled(IconButton)`
type ShortcutType = ComponentProps<typeof PlayerShortCut>["type"];

const ControlButtonWithTooltip = (
props: ComponentProps<typeof IconButton> & {
tooltip?: {
description: string;
type: ShortcutType;
};
},
) => {
if (!props.tooltip) return <IconButton {...props} />;
return (
<Tooltip
size="medium"
maxWidth="unset"
content={
<PlayerShortCut type={props.tooltip.type}>
{props.tooltip.description}
</PlayerShortCut>
}
type="light"
>
<IconButton {...props} />
</Tooltip>
);
};

export const ControlButton = styled(ControlButtonWithTooltip)`
color: ${({ theme }) => theme.palette.grey[700]};
`;
33 changes: 18 additions & 15 deletions src/stories/player/parts/controls.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { useVideoContext } from "@appquality/stream-player";
import { MouseEvent, useCallback, useEffect, useRef, useState } from "react";
import styled from "styled-components";
import useDebounce from "../../../hooks/useDebounce";
import { IBookmark, PlayerI18n, WrapperProps } from "../_types";
import { useProgressContext } from "../context/progressContext";
import { formatDuration } from "../utils";
import { AudioButton } from "./audioButton";
import { Bookmark } from "./bookmark";
import { ControlsGroupCenter } from "./controlsCenterGroup";
import { CutStart } from "./CutStart";
import { Cutter } from "./cutterButton";
import { FullScreenButton } from "./fullScreenButton";
import { ProgressBar } from "./progress";
import { useProgressContext } from "../context/progressContext";
import { TimeLabel } from "./timeLabel";
import { PlayerTooltip } from "./tooltip";
import { formatDuration } from "../utils";
import useDebounce from "../../../hooks/useDebounce";
import { CutStart } from "./CutStart";

export const ControlsWrapper = styled.div<WrapperProps>`
${({ showControls }) =>
Expand Down Expand Up @@ -114,7 +114,7 @@ export const Controls = ({

return 0;
},
[progressRef, duration]
[progressRef, duration],
);

const getProgress = useCallback(
Expand All @@ -125,7 +125,7 @@ export const Controls = ({

return (current / duration) * 100;
},
[context.part.start, duration]
[context.part.start, duration],
);

const handleSkipAhead = useCallback(
Expand All @@ -134,7 +134,12 @@ export const Controls = ({
setCurrentTime(time);
setProgress(getProgress(time));
},
[getVideoPositionFromEvent, context.part.start, setCurrentTime, getProgress]
[
getVideoPositionFromEvent,
context.part.start,
setCurrentTime,
getProgress,
],
);

const onMouseEvent = (e: MouseEvent<HTMLDivElement>) => {
Expand All @@ -161,7 +166,7 @@ export const Controls = ({
if (!activeBookmark || !marks) return;

const currentObsIndex = marks.findIndex(
(mark) => mark.id === activeBookmark.id
(mark) => mark.id === activeBookmark.id,
);
const value = (newX / clientW) * duration + context.part.start;

Expand All @@ -178,7 +183,7 @@ export const Controls = ({
setMarks(newMarks);
setUpdatedMark(updatedMark);
},
[activeBookmark, context.part.start, duration, fromEnd, marks]
[activeBookmark, context.part.start, duration, fromEnd, marks],
);

useEffect(() => {
Expand Down Expand Up @@ -236,15 +241,13 @@ export const Controls = ({
</ProgressContainer>

<ControlsBar>
<StyledDiv
style={{ width: "20%", justifyContent: "start"}}
>
<AudioButton />
<StyledDiv style={{ width: "20%", justifyContent: "start" }}>
<AudioButton i18n={i18n} />
<TimeLabel current={relCurrentTime} duration={duration} />
</StyledDiv>
<ControlsGroupCenter style={{ width: "60%" }} />
<ControlsGroupCenter style={{ width: "60%" }} i18n={i18n} />

<StyledDiv style={{ width: "20%", justifyContent: "end" }}>
<StyledDiv style={{ width: "20%", justifyContent: "end" }}>
<Cutter
onCutHandler={onCutHandler}
isCutting={isCutting}
Expand Down
25 changes: 22 additions & 3 deletions src/stories/player/parts/controlsCenterGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { ReactComponent as PauseIcon } from "../../../assets/icons/pause-fill.sv
import { ReactComponent as PlayIcon } from "../../../assets/icons/play-fill.svg";
import { ReactComponent as PreviousIcon } from "../../../assets/icons/previous-fill.svg";
import { SM } from "../../typography/typescale";
import { ControlButton } from "./controlButton";
import { PlayerI18n } from "../_types";
import { getNextPlaybackRate } from "../utils";
import { ControlButton } from "./controlButton";

const StyledDiv = styled.div`
display: flex;
Expand All @@ -17,7 +18,11 @@ const StyledDiv = styled.div`
gap: ${({ theme }) => theme.space.xxs};
`;

export const ControlsGroupCenter = (props: HTMLAttributes<HTMLDivElement>) => {
export const ControlsGroupCenter = (
props: HTMLAttributes<HTMLDivElement> & {
i18n?: PlayerI18n;
},
) => {
const [playBackRate, setPlayBackRate] = useState<number>(1);
const { context, togglePlay } = useVideoContext();

Expand Down Expand Up @@ -62,10 +67,20 @@ export const ControlsGroupCenter = (props: HTMLAttributes<HTMLDivElement>) => {
onRewind();
e.stopPropagation();
}}
tooltip={{
description: props.i18n?.backward || "Backward",
type: "backward",
}}
>
<RewindIcon />
</ControlButton>
<ControlButton onClick={togglePlay}>
<ControlButton
onClick={togglePlay}
tooltip={{
description: props.i18n?.playpause || "Play/Pause",
type: "play/pause",
}}
>
{isPlaying ? (
<PauseIcon style={{ width: "20px", height: "20px" }} />
) : (
Expand All @@ -78,6 +93,10 @@ export const ControlsGroupCenter = (props: HTMLAttributes<HTMLDivElement>) => {
onForward();
e.stopPropagation();
}}
tooltip={{
description: props.i18n?.forward || "Forward",
type: "forward",
}}
>
<ForwardIcon />
</ControlButton>
Expand Down
73 changes: 41 additions & 32 deletions src/stories/player/parts/cutterButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { useVideoContext } from "@appquality/stream-player";
import { styled } from "styled-components";
import { ReactComponent as TagIcon } from "../../../assets/icons/tag-stroke.svg";
import { ReactComponent as PlusIcon } from "../assets/plus.svg";
import { Button } from "../../buttons/button";
import { PlayerI18n } from "../_types";
import { Tooltip } from "../../tooltip";
import { Span } from "../../typography/span";
import { styled } from "styled-components";
import { PlayerI18n } from "../_types";
import { ReactComponent as PlusIcon } from "../assets/plus.svg";
import { PlayerShortCut } from "../shortcuts";

// Prevent button from breaking on smaller screens
const StyledButton = styled(Button)`
Expand All @@ -27,35 +29,42 @@ export const Cutter = ({
if (!onCutHandler) return null;

return (
<StyledButton
isPrimary
isAccent={!isCutting}
onClick={(e) => {
if (videoRef) {
onCutHandler(videoRef.currentTime);
}
e.stopPropagation();
}}
<Tooltip
type="light"
size="medium"
maxWidth="unset"
content={
<PlayerShortCut type="observation">
{i18n?.observations || "Start/stop new observation"}
</PlayerShortCut>
}
>
{isCutting ? (
<>
<Button.StartIcon>
<TagIcon />
</Button.StartIcon>
<Span>
{i18n?.onHighlight || "End observation"}
</Span>
</>
) : (
<>
<Button.StartIcon>
<PlusIcon />
</Button.StartIcon>
<Span>
{i18n?.beforeHighlight || "Start observation"}
</Span>
</>
)}
</StyledButton>
<StyledButton
isPrimary
isAccent={!isCutting}
onClick={(e) => {
if (videoRef) {
onCutHandler(videoRef.currentTime);
}
e.stopPropagation();
}}
>
{isCutting ? (
<>
<Button.StartIcon>
<TagIcon />
</Button.StartIcon>
<Span>{i18n?.onHighlight || "End observation"}</Span>
</>
) : (
<>
<Button.StartIcon>
<PlusIcon />
</Button.StartIcon>
<Span>{i18n?.beforeHighlight || "Start observation"}</Span>
</>
)}
</StyledButton>
</Tooltip>
);
};
Loading

0 comments on commit 86e5243

Please sign in to comment.