Skip to content

Commit

Permalink
[B2BP-841] - VideoImage "stop" feature (#382)
Browse files Browse the repository at this point in the history
* implement "stop" function

* commit changeset

* commit review changes

* commit change names

* commit review changes
  • Loading branch information
Meolocious authored Jul 30, 2024
1 parent 545232b commit e220164
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/fresh-cars-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nextjs-website": minor
---

Implement "stop" video function
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const renderVideo = ({
loop,
autoplay,
fallback,
onClick,
onVideoEnd,
}: RenderVideoProps) => {
// Determine the type based on the structure of src
Expand All @@ -46,6 +47,7 @@ export const renderVideo = ({
loop={loop}
autoPlay={autoplay}
onEnded={onVideoEnd}
onClick={onClick}
style={{
overflow: 'hidden',
width: '100%',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ const VideoImage = (props: VideoImageProps) => {
theme,
fallback,
playButtonLabel,
pausedplayButtonLabel,
isCentered = false,
} = props;
const videoRef = useRef<HTMLVideoElement>(null);
const isVisible = useIsVisible(videoRef);
const [error, setError] = useState(false);
const [isPlaying, setIsPlaying] = useState(false);
const [videoState, setVideoState] = useState<'playing' | 'paused' | 'stopped'>('stopped');

const textColor = TextColor(theme);

Expand All @@ -41,15 +42,25 @@ const VideoImage = (props: VideoImageProps) => {
}, [isVisible]);

const play = (e?: React.MouseEvent) => {
try {
e?.preventDefault();
videoRef.current?.play();
setIsPlaying(true);
} catch (error) {}
e?.preventDefault();
if (videoRef.current) {
videoRef.current.play().then(() => {
setVideoState('playing');
}).catch(() => {
// Handle play error
});
}
};

const handleVideoEnd = () => {
setIsPlaying(false);
setVideoState('stopped');
};

const pause = () => {
if (videoRef.current) {
videoRef.current.pause();
setVideoState('paused');
}
};

const isImage = (src: string) => {
Expand All @@ -67,7 +78,7 @@ const VideoImage = (props: VideoImageProps) => {
<div
style={{ maxHeight: '600px', position: 'relative', overflow: 'hidden' }}
>
{!full && !isPlaying && (
{!full && videoState !== 'playing' && (
<div
style={{
position: 'absolute',
Expand Down Expand Up @@ -97,7 +108,9 @@ const VideoImage = (props: VideoImageProps) => {
zIndex: 50,
}}
>
<VideoText title={title} subtitle={subtitle} theme={theme} />
{videoState === 'stopped' && (
<VideoText title={title} subtitle={subtitle} theme={theme} />
)}
{typeof src === 'string'
? !isImage(src) &&
isVideo(src) && (
Expand All @@ -124,7 +137,7 @@ const VideoImage = (props: VideoImageProps) => {
alignSelf: 'flex-start',
}}
>
{playButtonLabel}
{videoState === 'paused' ? pausedplayButtonLabel : playButtonLabel}
</p>
<PlayArrowIcon
sx={{
Expand Down Expand Up @@ -160,7 +173,7 @@ const VideoImage = (props: VideoImageProps) => {
alignSelf: 'flex-start',
}}
>
{playButtonLabel}
{videoState === 'paused' ? pausedplayButtonLabel : playButtonLabel}
</p>
<PlayArrowIcon
sx={{
Expand Down Expand Up @@ -189,6 +202,7 @@ const VideoImage = (props: VideoImageProps) => {
autoplay,
fallback,
onVideoEnd: handleVideoEnd,
onClick: pause,
})
: isImage(src.url)
? renderImage({
Expand All @@ -204,6 +218,7 @@ const VideoImage = (props: VideoImageProps) => {
autoplay,
fallback,
onVideoEnd: handleVideoEnd,
onClick: pause,
})}
</div>
{caption && (
Expand All @@ -217,4 +232,4 @@ const VideoImage = (props: VideoImageProps) => {
);
};

export default VideoImage;
export default VideoImage;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface VideoImageProps extends CommonProps {
reverse?: boolean;
fallback?: string;
playButtonLabel?: string;
pausedplayButtonLabel?: string;
isCentered: boolean;
}

Expand All @@ -34,6 +35,7 @@ export interface RenderVideoProps {
autoplay: boolean;
onVideoEnd: () => void;
fallback: React.ReactNode;
onClick?: () => void;
}

// Define TypeScript types for ImageProps
Expand Down
1 change: 1 addition & 0 deletions apps/nextjs-website/src/lib/fetch/types/PageSection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ const VideoImageSectionCodec = t.strict({
theme: t.union([t.literal('light'), t.literal('dark')]),
fallback: t.string,
playButtonLabel: t.string,
pausedplayButtonLabel: t.string,
sectionID: t.union([t.string, t.null]),
isCentered: t.boolean,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const createVideoImageDefaults = (theme: 'dark' | 'light') => ({
theme,
fallback: 'Ops! Something went wrong... Please try again later.',
playButtonLabel: 'Watch the video',
pausedplayButtonLabel: 'Resume video',
});

// Usage example
Expand Down

0 comments on commit e220164

Please sign in to comment.