From f4ffe6750534fd08403adc9f843eaf3a09f0d81a Mon Sep 17 00:00:00 2001 From: Stefan Hardegger Date: Fri, 1 May 2026 17:16:27 +0200 Subject: [PATCH] Fix image loading --- frontend/src/components/stories/StoryCard.tsx | 23 +++++++++++++++++++ frontend/src/contexts/AuthContext.tsx | 10 ++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/stories/StoryCard.tsx b/frontend/src/components/stories/StoryCard.tsx index 8c9659c..e3730a3 100644 --- a/frontend/src/components/stories/StoryCard.tsx +++ b/frontend/src/components/stories/StoryCard.tsx @@ -8,6 +8,27 @@ import { storyApi, getImageUrl } from '../../lib/api'; import Button from '../ui/Button'; import TagDisplay from '../tags/TagDisplay'; +// Detects systemic image load failures (e.g. wrong library ID) and reloads the page. +// Guards against infinite loops: max 2 auto-reloads per session. +const imageErrorTracker = { + errors: [] as number[], + reload() { + const count = parseInt(sessionStorage.getItem('storycove-reload-count') || '0'); + if (count < 2) { + sessionStorage.setItem('storycove-reload-count', String(count + 1)); + window.location.reload(); + } + }, + report() { + const now = Date.now(); + this.errors = this.errors.filter(t => now - t < 3000); + this.errors.push(now); + if (this.errors.length >= 3) { + this.reload(); + } + } +}; + interface StoryCardProps { story: Story; viewMode: 'grid' | 'list'; @@ -91,6 +112,7 @@ export default function StoryCard({ height={80} className="w-full h-full object-cover" unoptimized + onError={() => imageErrorTracker.report()} /> ) : (
@@ -209,6 +231,7 @@ export default function StoryCard({ height={400} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200" unoptimized + onError={() => imageErrorTracker.report()} /> ) : (
diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx index d6273cf..f613355 100644 --- a/frontend/src/contexts/AuthContext.tsx +++ b/frontend/src/contexts/AuthContext.tsx @@ -38,7 +38,10 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { // If authenticated, also load current library for image URLs if (authenticated) { try { - const response = await fetch('/api/libraries/current'); + const token = localStorage.getItem('auth-token'); + const response = await fetch('/api/libraries/current', { + headers: token ? { 'Authorization': `Bearer ${token}` } : {} + }); if (response.ok) { const library = await response.json(); setCurrentLibraryId(library.id); @@ -75,7 +78,10 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { // Load current library after successful login try { - const response = await fetch('/api/libraries/current'); + const token = localStorage.getItem('auth-token'); + const response = await fetch('/api/libraries/current', { + headers: token ? { 'Authorization': `Bearer ${token}` } : {} + }); if (response.ok) { const library = await response.json(); setCurrentLibraryId(library.id);