From 68d94c889c02b523569d0c6c2386af7f6bb8b892 Mon Sep 17 00:00:00 2001 From: Cao Yuhang Date: Thu, 20 Aug 2026 06:51:45 +0000 Subject: [PATCH] store: polish rich media previews --- website/snap/src/App.tsx | 32 +++++++++++++++++++++++++------- website/snap/src/styles.css | 2 +- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/website/snap/src/App.tsx b/website/snap/src/App.tsx index b5acd02be9..b253e28744 100644 --- a/website/snap/src/App.tsx +++ b/website/snap/src/App.tsx @@ -1,11 +1,12 @@ import { useEffect, useMemo, useState } from 'react'; +import { createPortal } from 'react-dom'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { - AppWindow, ArrowLeft, ArrowRight, BadgeCheck, Boxes, Check, ChevronDown, ChevronRight, - CircleGauge, Cloud, Database, Download, ExternalLink, GripVertical, HardDriveDownload, - LayoutGrid, Link2, LockKeyhole, LogOut, Menu, Package, Play, Plus, Search, Server, Settings, ShieldCheck, - Sparkles, Star, Store, UploadCloud, Users, X + AppWindow, ArrowLeft, ArrowRight, BadgeCheck, BookOpen, Boxes, Bug, Check, ChevronDown, ChevronRight, + CircleDollarSign, CircleGauge, Cloud, Database, Download, ExternalLink, FileCode2, Globe2, GripVertical, + HardDriveDownload, LayoutGrid, Link2, LockKeyhole, LogOut, Mail, Menu, MessageCircle, Package, Play, Plus, + Search, Server, Settings, ShieldCheck, Sparkles, Star, Store, UploadCloud, Users, X } from 'lucide-react'; import { abortPackageUpload, createUpstream, createVersion, finalizePackage, getAdminState, getAppDetails, getCatalog, getStorefront, requestPackageUpload, saveUpstreams, searchApps, uploadPackagePart } from './api'; import type { AdminState, StoreApp, StorefrontData, Upstream } from './types'; @@ -157,12 +158,28 @@ function linkDestination(value: string) { } } +function PublisherLinkIcon({ label }: { label: string }) { + switch (label.trim().toLowerCase()) { + case 'website': return ; + case 'contact': return ; + case 'documentation': return ; + case 'report a bug': return ; + case 'source code': return ; + case 'donate': return ; + case 'video': return ; + case 'community': return ; + case 'chat': return ; + default: return ; + } +} + function MediaGallery({ app }: { app: StoreApp }) { const items = [ - ...(app.screenshots || []).map(url => ({ kind: 'image' as const, url })), ...(app.videos || []).map(url => ({ kind: 'video' as const, url })), + ...(app.screenshots || []).map(url => ({ kind: 'image' as const, url })), ]; const [active, setActive] = useState(0); + const [expandedImage, setExpandedImage] = useState(null); useEffect(() => { if (active >= items.length) setActive(0); }, [active, items.length]); if (!items.length) return null; const current = items[active] || items[0]; @@ -170,9 +187,10 @@ function MediaGallery({ app }: { app: StoreApp }) { return

Preview

{items.length} {items.length === 1 ? 'item' : 'items'}
- {current.kind === 'image' ? {`${app.displayName} : embed ?