Various improvements

This commit is contained in:
Stefan Hardegger
2025-08-21 13:55:38 +02:00
parent 35a5825e76
commit a660056003
11 changed files with 829 additions and 55 deletions

View File

@@ -1,7 +1,7 @@
'use client';
import { useState, useEffect } from 'react';
import { searchApi, tagApi } from '../../lib/api';
import { searchApi, tagApi, getImageUrl } from '../../lib/api';
import { Story, Tag } from '../../types/api';
import { Input } from '../ui/Input';
import Button from '../ui/Button';
@@ -239,7 +239,7 @@ export default function CollectionForm({
{(coverImagePreview || initialData?.coverImagePath) && (
<div className="w-20 h-24 rounded overflow-hidden bg-gray-100">
<img
src={coverImagePreview || (initialData?.coverImagePath ? `/images/${initialData.coverImagePath}` : '')}
src={coverImagePreview || (initialData?.coverImagePath ? getImageUrl(initialData.coverImagePath) : '')}
alt="Cover preview"
className="w-full h-full object-cover"
/>

View File

@@ -2,7 +2,7 @@
import { useState, useEffect, useRef, useCallback } from 'react';
import { StoryWithCollectionContext } from '../../types/api';
import { storyApi } from '../../lib/api';
import { storyApi, getImageUrl } from '../../lib/api';
import Button from '../ui/Button';
import TagDisplay from '../tags/TagDisplay';
import Link from 'next/link';
@@ -212,7 +212,7 @@ export default function CollectionReadingView({
{story.coverPath && (
<div className="flex-shrink-0">
<img
src={`/images/${story.coverPath}`}
src={getImageUrl(story.coverPath)}
alt={`${story.title} cover`}
className="w-32 h-40 object-cover rounded-lg mx-auto md:mx-0"
/>

View File

@@ -6,6 +6,7 @@ import Button from '../ui/Button';
import { Input } from '../ui/Input';
import LibrarySwitchLoader from '../ui/LibrarySwitchLoader';
import { useLibrarySwitch } from '../../hooks/useLibrarySwitch';
import { setCurrentLibraryId, clearLibraryCache } from '../../lib/api';
interface Library {
id: string;
@@ -65,6 +66,8 @@ export default function LibrarySettings() {
if (response.ok) {
const data = await response.json();
setCurrentLibrary(data);
// Set the library ID for image URL generation
setCurrentLibraryId(data.id);
}
} catch (error) {
console.error('Failed to load current library:', error);
@@ -87,6 +90,8 @@ export default function LibrarySettings() {
};
const handleSwitchComplete = () => {
// Clear the library cache so images use the new library
clearLibraryCache();
// Refresh the page to reload with new library context
router.refresh();
window.location.reload();

View File

@@ -2,7 +2,7 @@
import { createContext, useContext, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { authApi, setGlobalAuthFailureHandler } from '../lib/api';
import { authApi, setGlobalAuthFailureHandler, setCurrentLibraryId } from '../lib/api';
import { preloadSanitizationConfig } from '../lib/sanitization';
interface AuthContextType {
@@ -34,6 +34,19 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
try {
const authenticated = authApi.isAuthenticated();
setIsAuthenticated(authenticated);
// If authenticated, also load current library for image URLs
if (authenticated) {
try {
const response = await fetch('/api/libraries/current');
if (response.ok) {
const library = await response.json();
setCurrentLibraryId(library.id);
}
} catch (error) {
console.error('Failed to load current library:', error);
}
}
} catch (error) {
console.error('Auth check failed:', error);
setIsAuthenticated(false);
@@ -59,6 +72,17 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
try {
await authApi.login(password);
setIsAuthenticated(true);
// Load current library after successful login
try {
const response = await fetch('/api/libraries/current');
if (response.ok) {
const library = await response.json();
setCurrentLibraryId(library.id);
}
} catch (error) {
console.error('Failed to load current library after login:', error);
}
} catch (error) {
console.error('Login failed:', error);
throw error;

View File

@@ -678,9 +678,34 @@ export const databaseApi = {
},
};
// Image utility
// Library context for images - will be set by a React context provider
let currentLibraryId: string | null = null;
// Set the current library ID (called by library context or components)
export const setCurrentLibraryId = (libraryId: string | null): void => {
currentLibraryId = libraryId;
};
// Get current library ID synchronously (fallback to 'default')
export const getCurrentLibraryId = (): string => {
return currentLibraryId || 'default';
};
// Clear library cache when switching libraries
export const clearLibraryCache = (): void => {
currentLibraryId = null;
};
// Image utility - now library-aware
export const getImageUrl = (path: string): string => {
if (!path) return '';
// Images are served directly by nginx at /images/
return `/images/${path}`;
// For compatibility during transition, handle both patterns
if (path.startsWith('http')) {
return path; // External URL
}
// Use library-aware API endpoint
const libraryId = getCurrentLibraryId();
return `/api/files/images/${libraryId}/${path}`;
};