pages cache

This commit is contained in:
alma 2025-05-04 16:32:11 +02:00
parent 89e3a5362e
commit 4678ec0cc9
2 changed files with 170 additions and 7 deletions

View File

@ -71,6 +71,12 @@ export default function CarnetPage() {
// Cache for Nextcloud folders
const foldersCache = useRef<{ folders: string[]; timestamp: number } | null>(null);
// Cache for notes list (Panel 2)
const notesCache = useRef<Record<string, { notes: Note[]; timestamp: number }>>({});
// Cache for note content (Panel 3)
const noteContentCache = useRef<Record<string, { content: string; timestamp: number }>>({});
// Clear folder cache on component mount to ensure fresh data
useEffect(() => {
@ -288,13 +294,63 @@ export default function CarnetPage() {
const folderLowercase = selectedFolder.toLowerCase();
console.log(`Fetching notes from folder: ${folderLowercase}`);
// Use direct storage API instead of adapter
// Check in-memory cache first
const cacheKey = `${session?.user?.id}-${folderLowercase}`;
const cachedNotes = notesCache.current[cacheKey];
const CACHE_EXPIRATION = 5 * 60 * 1000; // 5 minutes in milliseconds
if (cachedNotes && (Date.now() - cachedNotes.timestamp) < CACHE_EXPIRATION) {
console.log(`Using cached notes for ${folderLowercase} folder`);
setNotes(cachedNotes.notes);
setIsLoadingNotes(false);
return;
}
// Check localStorage cache if in-memory cache is not available
try {
const localStorageKey = `notes-cache-${cacheKey}`;
const storedCache = localStorage.getItem(localStorageKey);
if (storedCache) {
const { notes, timestamp } = JSON.parse(storedCache);
if ((Date.now() - timestamp) < CACHE_EXPIRATION) {
console.log(`Using localStorage cached notes for ${folderLowercase} folder`);
setNotes(notes);
// Update in-memory cache
notesCache.current[cacheKey] = { notes, timestamp };
setIsLoadingNotes(false);
return;
}
}
} catch (error) {
console.error('Error accessing localStorage notes cache:', error);
}
// Use direct storage API instead of adapter if cache is not available or expired
const response = await fetch(`/api/storage/files?folder=${folderLowercase}`);
if (response.ok) {
const data = await response.json();
console.log(`Fetched ${data.length} notes from ${folderLowercase} folder`);
// Update state
setNotes(data);
// Update both caches
const newTimestamp = Date.now();
notesCache.current[cacheKey] = { notes: data, timestamp: newTimestamp };
try {
localStorage.setItem(`notes-cache-${cacheKey}`, JSON.stringify({
notes: data,
timestamp: newTimestamp
}));
} catch (error) {
console.error('Error saving notes to localStorage:', error);
}
} else {
console.error('Error fetching notes:', await response.text());
setNotes([]);
@ -335,6 +391,39 @@ export default function CarnetPage() {
});
if (response.ok) {
// Invalidate the cache for this folder to ensure fresh data on next fetch
const cacheKey = `${session?.user?.id}-${selectedFolder.toLowerCase()}`;
// Remove from in-memory cache
if (notesCache.current[cacheKey]) {
delete notesCache.current[cacheKey];
}
// Remove from localStorage cache
try {
localStorage.removeItem(`notes-cache-${cacheKey}`);
} catch (error) {
console.error('Error removing notes from localStorage:', error);
}
// Update the content cache for this note
if (payload.id) {
noteContentCache.current[payload.id] = {
content: payload.content,
timestamp: Date.now()
};
// Update localStorage cache
try {
localStorage.setItem(`note-content-${payload.id}`, JSON.stringify({
content: payload.content,
timestamp: Date.now()
}));
} catch (error) {
console.error('Error saving note content to localStorage:', error);
}
}
// Refresh the list of notes
fetchNotes();
} else {

View File

@ -31,6 +31,10 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
const saveTimeout = useRef<NodeJS.Timeout>();
const router = useRouter();
const { data: session, status } = useSession();
// Content cache for notes
const contentCache = useRef<Record<string, { content: string; timestamp: number }>>({});
const CACHE_EXPIRATION = 15 * 60 * 1000; // 15 minutes in milliseconds
useEffect(() => {
// Redirect to login if not authenticated
@ -44,8 +48,42 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
if (note?.id) {
setIsLoading(true);
setError(null);
// First check in-memory cache
const cachedContent = contentCache.current[note.id];
if (cachedContent && (Date.now() - cachedContent.timestamp) < CACHE_EXPIRATION) {
console.log(`Using cached content for note ${note.title}`);
setContent(cachedContent.content);
setIsLoading(false);
return;
}
// Then check localStorage cache
try {
const response = await fetch(`/api/nextcloud/files/content?id=${note.id}`);
const localStorageKey = `note-content-${note.id}`;
const storedCache = localStorage.getItem(localStorageKey);
if (storedCache) {
const { content, timestamp } = JSON.parse(storedCache);
if ((Date.now() - timestamp) < CACHE_EXPIRATION) {
console.log(`Using localStorage cached content for note ${note.title}`);
setContent(content);
// Update in-memory cache
contentCache.current[note.id] = { content, timestamp };
setIsLoading(false);
return;
}
}
} catch (error) {
console.error('Error accessing localStorage content cache:', error);
}
// If cache miss, fetch from API
try {
const response = await fetch(`/api/storage/files/content?path=${encodeURIComponent(note.id)}`);
if (response.status === 401) {
console.error('Authentication error, redirecting to login');
router.push('/signin');
@ -57,6 +95,19 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
}
const data = await response.json();
setContent(data.content);
// Update both caches
const newTimestamp = Date.now();
contentCache.current[note.id] = { content: data.content, timestamp: newTimestamp };
try {
localStorage.setItem(`note-content-${note.id}`, JSON.stringify({
content: data.content,
timestamp: newTimestamp
}));
} catch (error) {
console.error('Error saving content to localStorage:', error);
}
} catch (error) {
console.error('Error fetching note content:', error);
setError('Failed to load note content. Please try again later.');
@ -77,7 +128,7 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
setTitle('');
setContent('');
}
}, [note, router]);
}, [note, router, CACHE_EXPIRATION]);
const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setTitle(e.target.value);
@ -109,11 +160,14 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
setIsSaving(true);
setError(null);
try {
const endpoint = note?.id ? '/api/nextcloud/files' : '/api/nextcloud/files';
// Construct the full note ID if it doesn't exist yet
const noteId = note?.id || `user-${session.user.id}/${currentFolder.toLowerCase()}/${title}${title.endsWith('.md') ? '' : '.md'}`;
const endpoint = '/api/storage/files';
const method = note?.id ? 'PUT' : 'POST';
console.log('Saving note:', {
id: note?.id,
id: noteId,
title,
folder: currentFolder,
contentLength: content.length
@ -125,10 +179,10 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: note?.id,
id: noteId,
title,
content,
folder: currentFolder
folder: currentFolder.toLowerCase()
}),
});
@ -151,6 +205,26 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
const savedNote = await response.json();
console.log('Note saved successfully:', savedNote);
// Update content cache after successful save
const newTimestamp = Date.now();
// Update in-memory cache
contentCache.current[noteId] = {
content,
timestamp: newTimestamp
};
// Update localStorage cache
try {
localStorage.setItem(`note-content-${noteId}`, JSON.stringify({
content,
timestamp: newTimestamp
}));
} catch (error) {
console.error('Error updating content cache in localStorage:', error);
}
setError(null);
onSave?.({
...savedNote,