feat: uv config other feats

- add uv configuration for the backend
- update frontend to make auth work
- add new auth endpoints
- add bookmars feat
- add reader feat
This commit is contained in:
2026-06-03 22:06:01 -05:00
parent 730c748f5f
commit 6b4c0c43f8
137 changed files with 20319 additions and 2340 deletions
+50
View File
@@ -0,0 +1,50 @@
import { DEFAULT_BOOKMARK_HIGHLIGHT_COLOR } from "@/constants/bookmarkHighlightColors";
import { DEFAULT_BOOKMARK_HIGHLIGHT_COLOR } from "@/constants/bookmarkHighlightColors";
import type { Bookmark, MarkerEntry, MarkersByBook } from "@/types";
export function bookmarkToMarkerEntry(b: Bookmark): MarkerEntry {
return {
id: b.id,
ebook_id: b.ebook,
ebook_title: b.ebook_title,
epub_cfi: b.epub_cfi,
chapter_index: b.chapter_index,
chapter_title: b.chapter_title,
page: b.page,
location_text: b.location_text,
content: b.content,
highlight_color: b.highlight_color ?? DEFAULT_BOOKMARK_HIGHLIGHT_COLOR,
created_at: b.created_at,
updated_at: b.updated_at,
};
}
export function sortMarkers(a: MarkerEntry, b: MarkerEntry): number {
if (a.chapter_index !== b.chapter_index) {
return a.chapter_index - b.chapter_index;
}
return a.epub_cfi.localeCompare(b.epub_cfi);
}
export function groupMarkersByBook(bookmarks: Bookmark[]): MarkersByBook[] {
const map = new Map<number, MarkersByBook>();
for (const b of bookmarks) {
const entry = bookmarkToMarkerEntry(b);
const existing = map.get(b.ebook);
if (existing) {
existing.markers.push(entry);
} else {
map.set(b.ebook, {
ebookId: b.ebook,
ebookTitle: b.ebook_title,
markers: [entry],
});
}
}
const groups = Array.from(map.values());
for (const g of groups) {
g.markers.sort(sortMarkers);
}
groups.sort((a, b) => a.ebookTitle.localeCompare(b.ebookTitle));
return groups;
}