diff --git a/frontend/src/components/MemeDetail.tsx b/frontend/src/components/MemeDetail.tsx index f70709f..e5c0f54 100644 --- a/frontend/src/components/MemeDetail.tsx +++ b/frontend/src/components/MemeDetail.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { X, Minimize2, Trash2, Edit2, Check, Layers, FolderOpen, Inbox, ScanText, ChevronDown, ChevronUp } from 'lucide-react'; +import { X, Minimize2, Trash2, Edit2, Check, Layers, FolderOpen, Inbox, ScanText, ChevronDown, ChevronUp, ExternalLink, Image, Info } from 'lucide-react'; import { useMeme, useDeleteMeme, useUpdateMeme, useMoveMeme, useCollections } from '../hooks/useMemes'; import { useAuth } from '../hooks/useAuth'; import { SharePanel } from './SharePanel'; @@ -39,6 +39,7 @@ export function MemeDetail({ memeId, onClose }: Props) { const [editTags, setEditTags] = useState(''); const [showRescale, setShowRescale] = useState(false); const [activeChild, setActiveChild] = useState(null); + const [mobileTab, setMobileTab] = useState<'image' | 'details'>('image'); const meme = data; const displayMeme = activeChild ?? meme; @@ -79,16 +80,18 @@ export function MemeDetail({ memeId, onClose }: Props) { if (!meme) return null; + const isVideo = meme.mime_type.startsWith('video/'); + const fullSizeUrl = displayMeme ? api.imageUrl(displayMeme.file_path) : null; + return ( <> -
+
+ + {/* Modal — full screen on mobile, inset on desktop */} +
-
{/* Header */} -
+
{editing ? ( ) : ( -

{meme.title}

+

{meme.title}

)} -
+
{isAdmin && ( editing ? ( ) : ( - ) )} - {isAdmin && !meme.parent_id && !meme.mime_type.startsWith('video/') && ( + {isAdmin && !meme.parent_id && !isVideo && ( )} + {/* Full size link — always visible */} + {fullSizeUrl && ( + e.stopPropagation()} + className="flex items-center gap-1 text-sm px-2.5 py-1.5 rounded-lg bg-zinc-800 hover:bg-zinc-700 text-zinc-300 transition-colors" + title="Open full size" + > + + Full size + + )} {isAdmin && ( )} -
+ {/* Mobile tab bar */} +
+ + +
+ {/* Body */} -
- {/* Image / video panel */} -
+
+ + {/* Image / video panel — full height on mobile when image tab active */} +
{displayMeme && ( - displayMeme.mime_type.startsWith('video/') ? ( + isVideo ? (