feat(app): add real images to all seed content + universal SVG text fallbacks
- Songs: 19/21 now have iTunes album art URLs (2 niche Bitcoin artists use fallback) - Podcasts: 21/21 now have iTunes artwork URLs - News: 21/21 now have Unsplash topic images - Books: Fixed The Network State cover URL - Places: 21/21 now have photos (Unsplash + Wikimedia) - Added generateNewsFallback() and generateImageFallback() SVG generators - Updated NewsCard, NewsGrid, ImageCard to use SVG text fallback instead of emoji - Added error handling to PlaceCard and PlaceGrid for failed photo loads Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
982a0c6aa6
commit
c88e837cc9
@@ -106,6 +106,38 @@ export function generateSongCoverFallback(title: string, artist?: string): strin
|
||||
return `data:image/svg+xml,${encodeURIComponent(svg)}`
|
||||
}
|
||||
|
||||
/** News article fallback — newspaper style with category badge */
|
||||
export function generateNewsFallback(title: string, source?: string): string {
|
||||
const hue = [...(title + (source ?? ''))].reduce((acc, c) => acc + c.charCodeAt(0), 0) % 360
|
||||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
|
||||
<rect width="200" height="200" fill="hsl(${hue}, 18%, 10%)"/>
|
||||
<rect x="3" y="3" width="194" height="194" rx="12" fill="none" stroke="hsl(${hue}, 22%, 18%)" stroke-width="1"/>
|
||||
<text x="100" y="72" text-anchor="middle" fill="hsl(${hue}, 20%, 22%)" font-family="Georgia,'Times New Roman',serif" font-size="10" font-weight="400" letter-spacing="3">NEWS</text>
|
||||
<line x1="50" y1="82" x2="150" y2="82" stroke="hsl(${hue}, 22%, 17%)" stroke-width="0.8"/>
|
||||
<line x1="40" y1="100" x2="160" y2="100" stroke="hsl(${hue}, 18%, 16%)" stroke-width="3"/>
|
||||
<line x1="50" y1="112" x2="150" y2="112" stroke="hsl(${hue}, 18%, 14%)" stroke-width="2"/>
|
||||
<line x1="55" y1="122" x2="145" y2="122" stroke="hsl(${hue}, 18%, 13%)" stroke-width="1.5"/>
|
||||
<line x1="60" y1="132" x2="140" y2="132" stroke="hsl(${hue}, 18%, 13%)" stroke-width="1"/>
|
||||
${source ? `<text x="100" y="165" text-anchor="middle" fill="hsl(${hue}, 25%, 40%)" font-family="system-ui,sans-serif" font-size="9" font-weight="400">${escapeXml(source.length > 22 ? source.slice(0, 20) + '…' : source)}</text>` : ''}
|
||||
</svg>`
|
||||
return `data:image/svg+xml,${encodeURIComponent(svg)}`
|
||||
}
|
||||
|
||||
/** Image fallback — picture frame style */
|
||||
export function generateImageFallback(title: string): string {
|
||||
const hue = [...title].reduce((acc, c) => acc + c.charCodeAt(0), 0) % 360
|
||||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
|
||||
<rect width="200" height="200" fill="hsl(${hue}, 15%, 10%)"/>
|
||||
<rect x="3" y="3" width="194" height="194" rx="12" fill="none" stroke="hsl(${hue}, 20%, 18%)" stroke-width="1"/>
|
||||
<text x="100" y="72" text-anchor="middle" fill="hsl(${hue}, 18%, 22%)" font-family="system-ui,sans-serif" font-size="10" font-weight="500" letter-spacing="3">IMAGE</text>
|
||||
<rect x="60" y="85" width="80" height="60" rx="4" fill="none" stroke="hsl(${hue}, 25%, 25%)" stroke-width="1.5"/>
|
||||
<circle cx="80" cy="102" r="6" fill="hsl(${hue}, 30%, 30%)"/>
|
||||
<path d="M60 135 L85 115 L105 128 L120 118 L140 135 Z" fill="hsl(${hue}, 25%, 20%)"/>
|
||||
<text x="100" y="170" text-anchor="middle" fill="hsl(${hue}, 30%, 45%)" font-family="system-ui,sans-serif" font-size="10" font-weight="500">${escapeXml(title.length > 20 ? title.slice(0, 18) + '…' : title)}</text>
|
||||
</svg>`
|
||||
return `data:image/svg+xml,${encodeURIComponent(svg)}`
|
||||
}
|
||||
|
||||
/** Film poster fallback — cinematic sans-serif */
|
||||
export function generatePosterFallback(title: string, year?: number): string {
|
||||
const hue = [...title].reduce((acc, c) => acc + c.charCodeAt(0), 0) % 360
|
||||
|
||||
Reference in New Issue
Block a user