Files
PinchChat/src/hooks/useBookmarks.ts
Nicolas Varrot 3970e8a00c test: add unit tests for hooks (useBookmarks, useUpdateCheck)
- Export loadBookmarks/saveBookmarks and isNewer for testability
- Add 12 tests covering bookmark persistence and semver comparison
- Total: 165 tests passing
2026-02-20 09:04:38 +00:00

69 lines
2.0 KiB
TypeScript

import { useState, useCallback } from 'react';
const STORAGE_KEY = 'pinchchat-bookmarks';
export interface Bookmark {
messageId: string;
sessionKey: string;
preview: string;
timestamp: number;
bookmarkedAt: number;
}
export function loadBookmarks(): Bookmark[] {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (raw) return JSON.parse(raw) as Bookmark[];
} catch { /* noop */ }
return [];
}
export function saveBookmarks(bookmarks: Bookmark[]) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(bookmarks));
} catch { /* noop */ }
}
export function useBookmarks() {
const [bookmarks, setBookmarks] = useState<Bookmark[]>(loadBookmarks);
const toggle = useCallback((messageId: string, sessionKey: string, preview: string, timestamp: number) => {
setBookmarks(prev => {
const exists = prev.some(b => b.messageId === messageId);
const next = exists
? prev.filter(b => b.messageId !== messageId)
: [...prev, { messageId, sessionKey, preview: preview.slice(0, 120), timestamp, bookmarkedAt: Date.now() }];
saveBookmarks(next);
return next;
});
}, []);
const isBookmarked = useCallback((messageId: string) => {
return bookmarks.some(b => b.messageId === messageId);
}, [bookmarks]);
const getForSession = useCallback((sessionKey: string) => {
return bookmarks
.filter(b => b.sessionKey === sessionKey)
.sort((a, b) => a.timestamp - b.timestamp);
}, [bookmarks]);
const remove = useCallback((messageId: string) => {
setBookmarks(prev => {
const next = prev.filter(b => b.messageId !== messageId);
saveBookmarks(next);
return next;
});
}, []);
const clearSession = useCallback((sessionKey: string) => {
setBookmarks(prev => {
const next = prev.filter(b => b.sessionKey !== sessionKey);
saveBookmarks(next);
return next;
});
}, []);
return { bookmarks, toggle, isBookmarked, getForSession, remove, clearSession };
}