pages cache
This commit is contained in:
parent
89e3a5362e
commit
4678ec0cc9
@ -72,6 +72,12 @@ export default function CarnetPage() {
|
|||||||
// Cache for Nextcloud folders
|
// Cache for Nextcloud folders
|
||||||
const foldersCache = useRef<{ folders: string[]; timestamp: number } | null>(null);
|
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
|
// Clear folder cache on component mount to ensure fresh data
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
try {
|
try {
|
||||||
@ -288,13 +294,63 @@ export default function CarnetPage() {
|
|||||||
const folderLowercase = selectedFolder.toLowerCase();
|
const folderLowercase = selectedFolder.toLowerCase();
|
||||||
console.log(`Fetching notes from folder: ${folderLowercase}`);
|
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}`);
|
const response = await fetch(`/api/storage/files?folder=${folderLowercase}`);
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
console.log(`Fetched ${data.length} notes from ${folderLowercase} folder`);
|
console.log(`Fetched ${data.length} notes from ${folderLowercase} folder`);
|
||||||
|
|
||||||
|
// Update state
|
||||||
setNotes(data);
|
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 {
|
} else {
|
||||||
console.error('Error fetching notes:', await response.text());
|
console.error('Error fetching notes:', await response.text());
|
||||||
setNotes([]);
|
setNotes([]);
|
||||||
@ -335,6 +391,39 @@ export default function CarnetPage() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
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
|
// Refresh the list of notes
|
||||||
fetchNotes();
|
fetchNotes();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -32,6 +32,10 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: session, status } = useSession();
|
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(() => {
|
useEffect(() => {
|
||||||
// Redirect to login if not authenticated
|
// Redirect to login if not authenticated
|
||||||
if (status === 'unauthenticated') {
|
if (status === 'unauthenticated') {
|
||||||
@ -44,8 +48,42 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
|
|||||||
if (note?.id) {
|
if (note?.id) {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
setError(null);
|
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 {
|
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) {
|
if (response.status === 401) {
|
||||||
console.error('Authentication error, redirecting to login');
|
console.error('Authentication error, redirecting to login');
|
||||||
router.push('/signin');
|
router.push('/signin');
|
||||||
@ -57,6 +95,19 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
|
|||||||
}
|
}
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
setContent(data.content);
|
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) {
|
} catch (error) {
|
||||||
console.error('Error fetching note content:', error);
|
console.error('Error fetching note content:', error);
|
||||||
setError('Failed to load note content. Please try again later.');
|
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('');
|
setTitle('');
|
||||||
setContent('');
|
setContent('');
|
||||||
}
|
}
|
||||||
}, [note, router]);
|
}, [note, router, CACHE_EXPIRATION]);
|
||||||
|
|
||||||
const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setTitle(e.target.value);
|
setTitle(e.target.value);
|
||||||
@ -109,11 +160,14 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
|
|||||||
setIsSaving(true);
|
setIsSaving(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
try {
|
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';
|
const method = note?.id ? 'PUT' : 'POST';
|
||||||
|
|
||||||
console.log('Saving note:', {
|
console.log('Saving note:', {
|
||||||
id: note?.id,
|
id: noteId,
|
||||||
title,
|
title,
|
||||||
folder: currentFolder,
|
folder: currentFolder,
|
||||||
contentLength: content.length
|
contentLength: content.length
|
||||||
@ -125,10 +179,10 @@ export const Editor: React.FC<EditorProps> = ({ note, onSave, currentFolder = 'N
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
id: note?.id,
|
id: noteId,
|
||||||
title,
|
title,
|
||||||
content,
|
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();
|
const savedNote = await response.json();
|
||||||
console.log('Note saved successfully:', savedNote);
|
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);
|
setError(null);
|
||||||
onSave?.({
|
onSave?.({
|
||||||
...savedNote,
|
...savedNote,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user