Skip to content

Commit 138001b

Browse files
committed
Add playback status badge to video players
1 parent 26c4ca6 commit 138001b

File tree

5 files changed

+39
-8
lines changed

5 files changed

+39
-8
lines changed

apps/web/app/embed/[videoId]/_components/EmbedVideo.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const EmbedVideo = forwardRef<
5151
chapters?: { title: string; start: number }[];
5252
ownerName?: string | null;
5353
autoplay?: boolean;
54+
showPlaybackStatusBadge?: boolean;
5455
}
5556
>(
5657
(
@@ -61,6 +62,7 @@ export const EmbedVideo = forwardRef<
6162
chapters = [],
6263
ownerName,
6364
autoplay: _autoplay = false,
65+
showPlaybackStatusBadge = false,
6466
},
6567
ref,
6668
) => {
@@ -194,6 +196,7 @@ export const EmbedVideo = forwardRef<
194196
videoSrc={videoSrc}
195197
rawFallbackSrc={rawFallbackSrc}
196198
duration={data.duration}
199+
showPlaybackStatusBadge={showPlaybackStatusBadge}
197200
chaptersSrc={chaptersUrl || ""}
198201
captionsSrc={subtitleUrl || ""}
199202
videoRef={videoRef}

apps/web/app/embed/[videoId]/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ async function EmbedContent({
287287
chapters={initialAiData?.chapters || []}
288288
ownerName={videoOwner[0]?.name || null}
289289
autoplay={autoplay}
290+
showPlaybackStatusBadge={user?.id === video.ownerId}
290291
/>
291292
);
292293
}

apps/web/app/s/[videoId]/Share.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ export const Share = ({
440440
chapters={aiData?.chapters || []}
441441
aiGenerationStatus={aiData?.aiGenerationStatus}
442442
canRetryProcessing={viewerId === data.owner.id}
443+
showPlaybackStatusBadge={viewerId === data.owner.id}
443444
ref={playerRef}
444445
/>
445446
</div>

apps/web/app/s/[videoId]/_components/CapVideoPlayer.tsx

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
88
import { skipToken, useQuery, useQueryClient } from "@tanstack/react-query";
99
import clsx from "clsx";
1010
import { AnimatePresence, motion } from "framer-motion";
11-
import { AlertTriangleIcon } from "lucide-react";
11+
import { AlertTriangleIcon, InfoIcon } from "lucide-react";
1212
import { useCallback, useEffect, useRef, useState } from "react";
1313
import { toast } from "sonner";
1414
import { retryVideoProcessing } from "@/actions/video/retry-processing";
@@ -24,7 +24,6 @@ import {
2424
type ResolvedPlaybackSource,
2525
resolvePlaybackSource,
2626
} from "./playback-source";
27-
2827
import {
2928
MediaPlayer,
3029
MediaPlayerCaptions,
@@ -44,6 +43,7 @@ import {
4443
MediaPlayerVolume,
4544
MediaPlayerVolumeIndicator,
4645
} from "./video/media-player";
46+
import { Tooltip, TooltipContent, TooltipTrigger } from "./video/tooltip";
4747

4848
const { circumference } = getProgressCircleConfig();
4949

@@ -98,6 +98,7 @@ interface Props {
9898
hasCaptions?: boolean;
9999
canRetryProcessing?: boolean;
100100
duration?: number | null;
101+
showPlaybackStatusBadge?: boolean;
101102
}
102103

103104
export function CapVideoPlayer({
@@ -125,6 +126,7 @@ export function CapVideoPlayer({
125126
hasCaptions = false,
126127
canRetryProcessing = false,
127128
duration: fallbackDuration,
129+
showPlaybackStatusBadge = false,
128130
}: Props) {
129131
const [currentCue, setCurrentCue] = useState<string>("");
130132
const [controlsVisible, setControlsVisible] = useState(false);
@@ -461,11 +463,16 @@ export function CapVideoPlayer({
461463
(!resolvedSrc.isSuccess || Boolean(resolvedSrc.data));
462464
const showPlaybackResolutionError =
463465
hasError && !uploadProgress && !resolvedSrc.data && !resolvedSrc.isPending;
464-
const showRawPlaybackBadge = resolvedSrc.data?.type === "raw";
466+
const showRawPlaybackBadge =
467+
showPlaybackStatusBadge && resolvedSrc.data?.type === "raw";
465468
const rawPlaybackBadgeLabel =
466469
uploadProgressRaw?.status === "error"
467-
? "Previewing original upload"
468-
: "Processing for best quality...";
470+
? "Original upload"
471+
: "Optimizing video";
472+
const rawPlaybackBadgeDescription =
473+
uploadProgressRaw?.status === "error"
474+
? "The processed version is unavailable right now, so this page is playing the original uploaded file instead."
475+
: "This page is temporarily playing the original uploaded file while Cap finishes processing the optimized version for smoother playback and broader compatibility.";
469476
const blockPlaybackControls =
470477
(!videoLoaded && hasActiveProgress) || showUploadFailureOverlay;
471478

@@ -520,9 +527,25 @@ export function CapVideoPlayer({
520527
</div>
521528
</div>
522529
{showRawPlaybackBadge && (
523-
<div className="absolute top-3 left-3 bg-black/60 text-white text-xs px-2 py-1 rounded-full backdrop-blur-sm z-10">
524-
{rawPlaybackBadgeLabel}
525-
</div>
530+
<Tooltip>
531+
<TooltipTrigger asChild>
532+
<button
533+
type="button"
534+
className="absolute top-3 left-3 z-10 inline-flex items-center gap-1 rounded-full border border-white/10 bg-black/55 px-2 py-0.5 text-[11px] font-medium text-white/90 backdrop-blur-sm transition-colors hover:bg-black/70"
535+
aria-label={rawPlaybackBadgeDescription}
536+
>
537+
<InfoIcon className="size-3" />
538+
<span>{rawPlaybackBadgeLabel}</span>
539+
</button>
540+
</TooltipTrigger>
541+
<TooltipContent
542+
side="bottom"
543+
align="start"
544+
className="max-w-[260px] border border-white/10 bg-black/90 px-3 py-2 text-xs leading-relaxed text-white shadow-xl"
545+
>
546+
{rawPlaybackBadgeDescription}
547+
</TooltipContent>
548+
</Tooltip>
526549
)}
527550
{resolvedSrc.data && (
528551
<MediaPlayerVideo

apps/web/app/s/[videoId]/_components/ShareVideo.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const ShareVideo = forwardRef<
4343
areReactionStampsDisabled?: boolean;
4444
aiGenerationStatus?: AiGenerationStatus | null;
4545
canRetryProcessing?: boolean;
46+
showPlaybackStatusBadge?: boolean;
4647
}
4748
>(
4849
(
@@ -55,6 +56,7 @@ export const ShareVideo = forwardRef<
5556
areCommentStampsDisabled,
5657
areReactionStampsDisabled,
5758
canRetryProcessing,
59+
showPlaybackStatusBadge = false,
5860
},
5961
ref,
6062
) => {
@@ -217,6 +219,7 @@ export const ShareVideo = forwardRef<
217219
videoSrc={videoSrc}
218220
rawFallbackSrc={rawFallbackSrc}
219221
duration={data.duration}
222+
showPlaybackStatusBadge={showPlaybackStatusBadge}
220223
disableCaptions={areCaptionsDisabled ?? false}
221224
disableCommentStamps={areCommentStampsDisabled ?? false}
222225
disableReactionStamps={areReactionStampsDisabled ?? false}

0 commit comments

Comments
 (0)