This commit is contained in:
@@ -3,6 +3,7 @@ import { ArrowSquareOut, Play } from '@phosphor-icons/react';
|
||||
import { useAction } from 'convex/react';
|
||||
import { api } from '../../../../../convex/_generated/api';
|
||||
import { usePlatform } from '../../platform';
|
||||
import { PausedGif } from './PausedGif';
|
||||
import styles from './LinkEmbed.module.css';
|
||||
|
||||
interface UrlPreview {
|
||||
@@ -125,7 +126,15 @@ function useUrlPreview(url: string): UrlPreview | null {
|
||||
return preview;
|
||||
}
|
||||
|
||||
function DirectMediaEmbed({ url, type }: { url: string; type: 'video' | 'image' }) {
|
||||
function DirectMediaEmbed({
|
||||
url,
|
||||
type,
|
||||
onOpenGif,
|
||||
}: {
|
||||
url: string;
|
||||
type: 'video' | 'image';
|
||||
onOpenGif?: (url: string) => void;
|
||||
}) {
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
const [playing, setPlaying] = useState(false);
|
||||
|
||||
@@ -138,7 +147,7 @@ function DirectMediaEmbed({ url, type }: { url: string; type: 'video' | 'image'
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.embed}>
|
||||
<div className={`${styles.embed} ${styles.embedBare}`}>
|
||||
<div className={styles.directVideoWrapper}>
|
||||
<video
|
||||
ref={videoRef}
|
||||
@@ -172,8 +181,20 @@ function DirectMediaEmbed({ url, type }: { url: string; type: 'video' | 'image'
|
||||
);
|
||||
}
|
||||
|
||||
// GIFs (and other direct images) render through PausedGif so
|
||||
// the idle state freezes on the first frame and only animates
|
||||
// on hover. Click opens a fullscreen viewer via `onOpenGif` —
|
||||
// the parent MessageGroup owns the lightbox state and reuses
|
||||
// its existing ImageLightbox.
|
||||
const isGif = /\.gif(\?|#|$)/i.test(url);
|
||||
if (isGif) {
|
||||
return (
|
||||
<PausedGif url={url} onOpen={onOpenGif} className={styles.directGif} />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.embed}>
|
||||
<div className={`${styles.embed} ${styles.embedBare}`}>
|
||||
<a href={url} target="_blank" rel="noopener noreferrer">
|
||||
<img
|
||||
className={styles.directImage}
|
||||
@@ -188,12 +209,16 @@ function DirectMediaEmbed({ url, type }: { url: string; type: 'video' | 'image'
|
||||
|
||||
interface LinkEmbedProps {
|
||||
url: string;
|
||||
/** Called when the user clicks a paused GIF preview. The parent
|
||||
* owns the fullscreen viewer state (MessageGroup reuses its
|
||||
* existing ImageLightbox). Ignored for non-GIF embeds. */
|
||||
onOpenGif?: (url: string) => void;
|
||||
}
|
||||
|
||||
export function LinkEmbed({ url }: LinkEmbedProps) {
|
||||
export function LinkEmbed({ url, onOpenGif }: LinkEmbedProps) {
|
||||
const directType = isDirectMedia(url);
|
||||
if (directType) {
|
||||
return <DirectMediaEmbed url={url} type={directType} />;
|
||||
return <DirectMediaEmbed url={url} type={directType} onOpenGif={onOpenGif} />;
|
||||
}
|
||||
|
||||
const preview = useUrlPreview(url);
|
||||
|
||||
Reference in New Issue
Block a user