From 383506fc07e33fa1779a8785edff7df818a842d1 Mon Sep 17 00:00:00 2001 From: neon <18559658+neonsolstice@users.noreply.github.com> Date: Tue, 2 Jun 2026 05:34:05 +0000 Subject: [PATCH] feat(reader): support peeking books without tracking progress Implement a 'peek mode' that allows users to open and read books without updating their reading progress or creating reading sessions. Add a 'Peeking' banner in the reader and disable API calls in 'useReaderProgress' and 'useReadingSession' when tracking is disabled. Closes #161 --- .../book/components/BookCoverCard.vue | 26 +++- .../features/book/components/BookListRow.vue | 16 ++- .../book/components/BookQuickView.vue | 23 +++- .../__tests__/BookTableCells.spec.ts | 13 ++ .../components/detail/tabs/DetailsTab.vue | 128 ++++++++++++------ .../book/components/detail/tabs/FilesTab.vue | 18 ++- .../table/BookTableReadButtonCell.vue | 53 ++++++-- client/src/features/reader/ReaderView.vue | 38 ++++-- .../reader/audiobook/AudiobookReaderView.vue | 31 ++++- .../audiobook/composables/useAudioProgress.ts | 16 ++- .../src/features/reader/cbz/CbzReaderView.vue | 40 +++++- .../reader/epub/components/ReaderHeader.vue | 12 ++ .../__tests__/ReaderSidebar.spec.ts | 2 +- .../reader/pdf-v4/PdfV4ReaderView.vue | 52 ++++++- .../__tests__/useReaderProgress.spec.ts | 16 +++ .../__tests__/useReadingSession.spec.ts | 13 ++ .../shared/composables/useReaderProgress.ts | 18 ++- .../shared/composables/useReadingSession.ts | 24 +++- 18 files changed, 429 insertions(+), 110 deletions(-) diff --git a/client/src/features/book/components/BookCoverCard.vue b/client/src/features/book/components/BookCoverCard.vue index 5f0204954..bcd2e7b65 100644 --- a/client/src/features/book/components/BookCoverCard.vue +++ b/client/src/features/book/components/BookCoverCard.vue @@ -8,6 +8,7 @@ import { BookOpen, Check, Download, + Eye, ExternalLink, FolderPlus, Image, @@ -181,14 +182,19 @@ function handleArtworkError() { coverImageRatio.value = null } -function openFile(file: BookFileRef) { +function openFile(file: BookFileRef, mode?: 'peek') { router.push({ name: 'reader', params: { bookId: props.book.id, fileId: file.id }, - query: { format: file.format ?? 'epub' }, + query: mode === 'peek' ? { format: file.format ?? 'epub', mode } : { format: file.format ?? 'epub' }, }) } +function peekPrimaryFile() { + if (!primaryFile.value || isMissing.value) return + openFile(primaryFile.value, 'peek') +} + function openBookDetails() { void router.push({ name: 'book-detail', params: { bookId: props.book.id } }) } @@ -534,12 +540,12 @@ const secondaryLabelText = computed(() => resolveBookLabel(gridCardSecondaryLabe - Open + Read - Open + Read @@ -549,6 +555,10 @@ const secondaryLabelText = computed(() => resolveBookLabel(gridCardSecondaryLabe + + + Peek + resolveBookLabel(gridCardSecondaryLabe - Open + Read - Open + Read @@ -680,6 +690,10 @@ const secondaryLabelText = computed(() => resolveBookLabel(gridCardSecondaryLabe + + + Peek + coverUrl(props.book.id)) const { refreshing, refreshWithFeedback } = useRefreshMetadata() const coverAspectRatio = inject(COVER_ASPECT_RATIO_KEY, ref(DEFAULT_COVER_ASPECT_RATIO)) -function openFile(file: BookFileRef) { +function openFile(file: BookFileRef, mode?: 'peek') { router.push({ name: 'reader', params: { bookId: props.book.id, fileId: file.id }, - query: { format: file.format ?? 'epub' }, + query: mode === 'peek' ? { format: file.format ?? 'epub', mode } : { format: file.format ?? 'epub' }, }) } +function peekPrimaryFile() { + if (!primaryFile.value || isMissing.value) return + openFile(primaryFile.value, 'peek') +} + function openAuthorBrowse() { if (!authorQuery.value) return void router.push({ name: 'authors', query: { q: authorQuery.value } }) @@ -229,7 +235,11 @@ function openAuthorBrowse() { - Open + Read + + + + Peek diff --git a/client/src/features/book/components/BookQuickView.vue b/client/src/features/book/components/BookQuickView.vue index 7dd76b3b0..04e28a869 100644 --- a/client/src/features/book/components/BookQuickView.vue +++ b/client/src/features/book/components/BookQuickView.vue @@ -1,7 +1,7 @@