Fix Bookmarks restore from deletion (#43)

This commit is contained in:
Huang Xin
2024-12-25 22:02:01 +01:00
committed by GitHub
parent 72949e726f
commit 3d0a2b82ba
6 changed files with 41 additions and 19 deletions
@@ -41,7 +41,15 @@ const BookmarkToggler: React.FC<BookmarkTogglerProps> = ({ bookKey }) => {
createdAt: Date.now(),
updatedAt: Date.now(),
};
bookmarks.push(bookmark);
const existingBookmark = bookmarks.find(
(item) => item.type === 'bookmark' && item.cfi === cfi,
);
if (existingBookmark) {
existingBookmark.deletedAt = null;
existingBookmark.updatedAt = Date.now();
} else {
bookmarks.push(bookmark);
}
const updatedConfig = updateBooknotes(bookKey, bookmarks);
if (updatedConfig) {
saveConfig(envConfig, bookKey, updatedConfig, settings);
@@ -50,14 +58,15 @@ const BookmarkToggler: React.FC<BookmarkTogglerProps> = ({ bookKey }) => {
setIsBookmarked(false);
const start = CFI.collapse(cfi);
const end = CFI.collapse(cfi, true);
const updatedConfig = updateBooknotes(
bookKey,
bookmarks.filter(
(item) =>
item.type !== 'bookmark' ||
CFI.compare(start, item.cfi) * CFI.compare(end, item.cfi) > 0,
),
);
bookmarks.forEach((item) => {
if (
item.type === 'bookmark' &&
CFI.compare(start, item.cfi) * CFI.compare(end, item.cfi) <= 0
) {
item.deletedAt = Date.now();
}
});
const updatedConfig = updateBooknotes(bookKey, bookmarks);
if (updatedConfig) {
saveConfig(envConfig, bookKey, updatedConfig, settings);
}
@@ -72,7 +81,7 @@ const BookmarkToggler: React.FC<BookmarkTogglerProps> = ({ bookKey }) => {
const start = CFI.collapse(cfi);
const end = CFI.collapse(cfi, true);
const locationBookmarked = booknotes
.filter((booknote) => booknote.type === 'bookmark')
.filter((booknote) => booknote.type === 'bookmark' && !booknote.deletedAt)
.some((item) => CFI.compare(start, item.cfi) * CFI.compare(end, item.cfi) <= 0);
setIsBookmarked(locationBookmarked);
setBookmarkRibbonVisibility(bookKey, locationBookmarked);
@@ -20,8 +20,9 @@ export const useNotesSync = (bookKey: string) => {
const lastSyncTime = useRef<number>(0);
const syncTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
useEffect(() => {
if (!config?.location || !user) return;
const getNewNotes = () => {
if (!config?.location || !user) return [];
const bookNotes = config.booknotes ?? [];
const newNotes = bookNotes.filter(
(note) => lastSyncedAtNotes < note.updatedAt || lastSyncedAtNotes < (note.deletedAt ?? 0),
@@ -29,16 +30,23 @@ export const useNotesSync = (bookKey: string) => {
newNotes.forEach((note) => {
note.bookHash = bookHash;
});
return newNotes;
};
useEffect(() => {
if (!config?.location || !user) return;
const now = Date.now();
const timeSinceLastSync = now - lastSyncTime.current;
if (timeSinceLastSync > SYNC_NOTES_INTERVAL_SEC * 1000) {
lastSyncTime.current = now;
const newNotes = getNewNotes();
syncNotes(newNotes, bookHash, 'both');
} else {
if (syncTimeoutRef.current) clearTimeout(syncTimeoutRef.current);
syncTimeoutRef.current = setTimeout(
() => {
lastSyncTime.current = Date.now();
const newNotes = getNewNotes();
syncNotes(newNotes, bookHash, 'both');
syncTimeoutRef.current = null;
},
+4
View File
@@ -150,6 +150,8 @@ export async function POST(req: NextRequest) {
}
if (!serverData) {
// use server updated_at for new records
dbRec.updated_at = new Date().toISOString();
const { data: inserted, error: insertError } = await supabase
.from(table)
.insert(dbRec)
@@ -171,6 +173,8 @@ export async function POST(req: NextRequest) {
clientDeletedAt > serverDeletedAt || clientUpdatedAt > serverUpdatedAt;
if (clientIsNewer) {
// use server updated_at for updated records
dbRec.updated_at = new Date().toISOString();
const { data: updated, error: updateError } = await supabase
.from(table)
.update(dbRec)
+1 -1
View File
@@ -132,7 +132,7 @@ export abstract class BaseAppService implements AppService {
const existingBook = books.filter((b) => b.hash === hash)[0];
if (existingBook) {
if (existingBook.deletedAt) {
delete existingBook.deletedAt;
existingBook.deletedAt = null;
}
existingBook.updatedAt = Date.now();
}
+2 -2
View File
@@ -16,7 +16,7 @@ export interface Book {
createdAt: number;
updatedAt: number;
deletedAt?: number;
deletedAt?: number | null;
lastUpdated?: number; // deprecated in favor of updatedAt
}
@@ -39,7 +39,7 @@ export interface BookNote {
createdAt: number;
updatedAt: number;
deletedAt?: number;
deletedAt?: number | null;
}
export interface BookLayout {
+5 -4
View File
@@ -50,7 +50,7 @@ export const transformBookToDB = (book: unknown, userId: string): DBBook => {
tags: tags && JSON.stringify(tags),
created_at: new Date(createdAt).toISOString(),
updated_at: new Date(updatedAt).toISOString(),
deleted_at: deletedAt ? new Date(deletedAt).toISOString() : undefined,
deleted_at: deletedAt ? new Date(deletedAt).toISOString() : null,
};
};
@@ -67,7 +67,7 @@ export const transformBookFromDB = (dbBook: DBBook): Book => {
tags: tags && JSON.parse(tags),
createdAt: new Date(created_at!).getTime(),
updatedAt: new Date(updated_at!).getTime(),
deletedAt: deleted_at ? new Date(deleted_at!).getTime() : undefined,
deletedAt: deleted_at ? new Date(deleted_at!).getTime() : null,
};
};
@@ -87,7 +87,8 @@ export const transformBookNoteToDB = (bookNote: unknown, userId: string): DBBook
note,
created_at: new Date(createdAt).toISOString(),
updated_at: new Date(updatedAt).toISOString(),
deleted_at: deletedAt ? new Date(deletedAt).toISOString() : undefined,
// note that only null deleted_at is updated to the database, undefined is not
deleted_at: deletedAt ? new Date(deletedAt).toISOString() : null,
};
};
@@ -106,6 +107,6 @@ export const transformBookNoteFromDB = (dbBookNote: DBBookNote): BookNote => {
note,
createdAt: new Date(created_at!).getTime(),
updatedAt: new Date(updated_at!).getTime(),
deletedAt: deleted_at ? new Date(deleted_at!).getTime() : undefined,
deletedAt: deleted_at ? new Date(deleted_at!).getTime() : null,
};
};