mirror of
https://github.com/priyanshujain/margin.git
synced 2026-10-02 19:17:03 +00:00
fix(editor): prune chapter positions on delete and guard quota
Saved cursor/scroll and active-chapter entries accumulated per book forever and were never removed when a book was deleted. Add clearPositions and call it from the delete flow, and guard localStorage writes against quota or unavailable storage. Claude-Session: https://claude.ai/code/session_01RzTWrLiy4zGuw2hZSQGamk
This commit is contained in:
1 parent
608ba2f21b
commit
2f98f5ec1c
2 files changed
+21
-2
No files matched your search
@@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
|
|||||||
import { type BookSummary, createAndOpenBook, deleteBook, exampleBook, listBooks, loadBook, saveBook } from "../library";
|
import { type BookSummary, createAndOpenBook, deleteBook, exampleBook, listBooks, loadBook, saveBook } from "../library";
|
||||||
import type { Book } from "../model/book";
|
import type { Book } from "../model/book";
|
||||||
import { importEpub } from "../import/epub";
|
import { importEpub } from "../import/epub";
|
||||||
|
import { clearPositions } from "../editor/positions";
|
||||||
import { isDesktop } from "../ipc";
|
import { isDesktop } from "../ipc";
|
||||||
import { ConfirmDialog } from "./ConfirmDialog";
|
import { ConfirmDialog } from "./ConfirmDialog";
|
||||||
import { Icon } from "./Icon";
|
import { Icon } from "./Icon";
|
||||||
@@ -38,6 +39,7 @@ export function Library({ onOpen }: { onOpen: (book: Book) => void }) {
|
|||||||
const removeBook = async () => {
|
const removeBook = async () => {
|
||||||
if (!pendingDelete) return;
|
if (!pendingDelete) return;
|
||||||
await deleteBook(pendingDelete.id);
|
await deleteBook(pendingDelete.id);
|
||||||
|
clearPositions(pendingDelete.id);
|
||||||
setPendingDelete(null);
|
setPendingDelete(null);
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
|||||||
+19
-2
@@ -16,6 +16,14 @@ function readAll(): Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function write(key: string, value: unknown): void {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(key, JSON.stringify(value));
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function loadPosition(bookId: string, chapterId: string): ChapterPosition | null {
|
export function loadPosition(bookId: string, chapterId: string): ChapterPosition | null {
|
||||||
return readAll()[bookId]?.[chapterId] ?? null;
|
return readAll()[bookId]?.[chapterId] ?? null;
|
||||||
}
|
}
|
||||||
@@ -23,7 +31,7 @@ export function loadPosition(bookId: string, chapterId: string): ChapterPosition
|
|||||||
export function savePosition(bookId: string, chapterId: string, position: ChapterPosition): void {
|
export function savePosition(bookId: string, chapterId: string, position: ChapterPosition): void {
|
||||||
const all = readAll();
|
const all = readAll();
|
||||||
(all[bookId] ||= {})[chapterId] = position;
|
(all[bookId] ||= {})[chapterId] = position;
|
||||||
localStorage.setItem(KEY, JSON.stringify(all));
|
write(KEY, all);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ACTIVE_KEY = "margin-active-chapter";
|
const ACTIVE_KEY = "margin-active-chapter";
|
||||||
@@ -43,5 +51,14 @@ export function loadActiveChapter(bookId: string): string | null {
|
|||||||
export function saveActiveChapter(bookId: string, chapterId: string): void {
|
export function saveActiveChapter(bookId: string, chapterId: string): void {
|
||||||
const all = readActive();
|
const all = readActive();
|
||||||
all[bookId] = chapterId;
|
all[bookId] = chapterId;
|
||||||
localStorage.setItem(ACTIVE_KEY, JSON.stringify(all));
|
write(ACTIVE_KEY, all);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearPositions(bookId: string): void {
|
||||||
|
const positions = readAll();
|
||||||
|
const active = readActive();
|
||||||
|
delete positions[bookId];
|
||||||
|
delete active[bookId];
|
||||||
|
write(KEY, positions);
|
||||||
|
write(ACTIVE_KEY, active);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user