1.0.60
All checks were successful
Build and Release / build-and-release (push) Successful in 12m29s

This commit is contained in:
Bryan1029384756
2026-04-14 20:03:54 -05:00
parent b7a4cf4ce8
commit 965048f7d2
47 changed files with 2558 additions and 135 deletions

View File

@@ -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);