Skip to content

[TAS-5149] ✨ Implement annotation feature for EPUB reader#643

Merged
williamchong merged 17 commits intolikecoin:developfrom
nwingt:feature/annotation
Feb 26, 2026
Merged

[TAS-5149] ✨ Implement annotation feature for EPUB reader#643
williamchong merged 17 commits intolikecoin:developfrom
nwingt:feature/annotation

Conversation

@nwingt
Copy link
Member

@nwingt nwingt commented Jan 27, 2026

@nwingt nwingt requested a review from Copilot January 27, 2026 07:42
@notion-workspace
Copy link

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements an annotation (highlights + notes) feature for the EPUB reader, including persistence via Firestore-backed APIs and new UI components for creating/editing/navigating annotations.

Changes:

  • Added shared/server annotation types and Firestore utility functions for CRUD operations.
  • Introduced /api/books/:nftClassId/annotations endpoints (list/create/update/delete).
  • Updated the EPUB reader UI to render highlights, show a selection menu + modal editor, and display an annotations list; added i18n strings and color constants.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
shared/types/annotation.d.ts Adds shared annotation type definitions (color, base fields, create/update shapes).
server/types/annotation.d.ts Defines Firestore data shape for annotations.
server/utils/annotations.ts Firestore CRUD utilities for annotations under user/book documents.
server/api/books/[nftClassId]/annotations/index.get.ts Lists annotations for a user/book.
server/api/books/[nftClassId]/annotations/index.post.ts Creates an annotation with basic validation.
server/api/books/[nftClassId]/annotations/[annotationId].post.ts Updates annotation color/note.
server/api/books/[nftClassId]/annotations/[annotationId].delete.ts Deletes an annotation.
constants/annotations.ts Centralizes annotation color options and rgba mappings.
composables/use-annotations.ts Client composable for fetching and mutating annotations via the new APIs.
components/AnnotationsList.vue UI list for existing highlights/notes and navigation to a highlight.
components/AnnotationMenu.vue Context menu for selection-based highlight color + “note” action.
components/AnnotationModal.vue Modal UI for editing color and note, deleting highlights.
pages/reader/epub.vue Integrates selection handling, highlight rendering, and annotation UI into the EPUB reader.
i18n/locales/en.json Adds English strings for annotations UI.
i18n/locales/zh-Hant.json Adds Traditional Chinese strings for annotations UI.

@nwingt nwingt force-pushed the feature/annotation branch from 2755eb5 to 1baa810 Compare January 27, 2026 07:50
nwingt added a commit that referenced this pull request Jan 27, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Jan 27, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Jan 27, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Jan 29, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Jan 30, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Jan 30, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Jan 30, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Feb 1, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Feb 2, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 2, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Feb 2, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 3, 2026
✨ Implement annotation feature for EPUB reader
@nwingt nwingt force-pushed the feature/annotation branch from 1baa810 to 83b6ac7 Compare February 4, 2026 09:31
williamchong pushed a commit that referenced this pull request Feb 4, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 4, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 4, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 6, 2026
✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Feb 6, 2026
✨ Implement annotation feature for EPUB reader
@nwingt nwingt force-pushed the feature/annotation branch from 83b6ac7 to 4bc65b4 Compare February 6, 2026 07:20
nwingt added a commit that referenced this pull request Feb 6, 2026
✨ Implement annotation feature for EPUB reader
@nwingt nwingt force-pushed the feature/annotation branch from 4bc65b4 to 9a3f098 Compare February 6, 2026 09:23
nwingt added a commit that referenced this pull request Feb 6, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 6, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 6, 2026
✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 8, 2026
✨ Implement annotation feature for EPUB reader
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 8 comments.

Comment on lines +1150 to +1171
// Access via manager to get Contents array
const contents = rendition.value?.manager?.getContents()
const content = contents?.[0]
if (!content) {
isAnnotationMenuVisible.value = false
return
}

const cfiRange = content.cfiFromRange(range)
if (!cfiRange) {
isAnnotationMenuVisible.value = false
return
}

selectedText.value = text.slice(0, ANNOTATION_TEXT_MAX_LENGTH)
selectedCfi.value = cfiRange
selectedChapterTitle.value = activeNavItemLabel.value

const rect = range.getBoundingClientRect()
const iframe = renditionElement.value?.querySelector('iframe')
const iframeRect = iframe?.getBoundingClientRect()

Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleTextSelection always uses contents?.[0] and the first iframe to compute the CFI range and menu position. In paginated/spread rendering there can be multiple Contents/iframes; this can produce an incorrect CFI and misplace the menu when the selection is in a different view. Prefer selecting the content/iframe that matches the viewWindow (e.g., match content.window === viewWindow or iframe.contentWindow === viewWindow).

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 1 comment.

nwingt added a commit that referenced this pull request Feb 26, 2026
commit 959d68f
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 17:35:05 2026 +0800

    🎨 Update unused function param name

commit ff39b68
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:51:03 2026 +0800

    🎨 Use setHeaders instead of setResponseHeader

commit 2745979
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:38:10 2026 +0800

    🚸 Prevent system menu blocking annotation menu

commit 9d36efc
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:37:56 2026 +0800

    🐛 Fix annotation modal open when saving failed

commit ab1ad96
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:33 2026 +0800

    🎨 Sanitize annotations export filename

commit 75f7eef
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:06 2026 +0800

    🎨 Use UUID for temp annotation

commit e2537e3
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:31:51 2026 +0800

    🎨 Prevent memory leak

commit 69bfe0b
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:29:49 2026 +0800

    🥅 Guard annotation navigation

commit 511a24e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:20:53 2026 +0800

    🎨 Ensures annotations re-rendered when update

commit 11a5734
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:44:15 2026 +0800

    🔒 Truncate annotation text to max length on client side

commit f6b262c
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:22:44 2026 +0800

    🚸 Improve annotation UX

commit a208d2e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 23:34:22 2026 +0800

    🐛 Fix EventListener type mismatch in annotation highlight callback

commit a360ab4
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 10:30:29 2026 +0800

    🎨 Use typed Firestore collection

commit 50f1949
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 12 22:52:15 2026 +0800

    ✨ Support annotations export

commit b5e85f8
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Tue Jan 27 15:41:25 2026 +0800

    ✨ Implement annotation feature for EPUB reader
nwingt added a commit that referenced this pull request Feb 26, 2026
commit 959d68f
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 17:35:05 2026 +0800

    🎨 Update unused function param name

commit ff39b68
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:51:03 2026 +0800

    🎨 Use setHeaders instead of setResponseHeader

commit 2745979
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:38:10 2026 +0800

    🚸 Prevent system menu blocking annotation menu

commit 9d36efc
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:37:56 2026 +0800

    🐛 Fix annotation modal open when saving failed

commit ab1ad96
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:33 2026 +0800

    🎨 Sanitize annotations export filename

commit 75f7eef
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:06 2026 +0800

    🎨 Use UUID for temp annotation

commit e2537e3
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:31:51 2026 +0800

    🎨 Prevent memory leak

commit 69bfe0b
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:29:49 2026 +0800

    🥅 Guard annotation navigation

commit 511a24e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:20:53 2026 +0800

    🎨 Ensures annotations re-rendered when update

commit 11a5734
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:44:15 2026 +0800

    🔒 Truncate annotation text to max length on client side

commit f6b262c
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:22:44 2026 +0800

    🚸 Improve annotation UX

commit a208d2e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 23:34:22 2026 +0800

    🐛 Fix EventListener type mismatch in annotation highlight callback

commit a360ab4
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 10:30:29 2026 +0800

    🎨 Use typed Firestore collection

commit 50f1949
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 12 22:52:15 2026 +0800

    ✨ Support annotations export

commit b5e85f8
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Tue Jan 27 15:41:25 2026 +0800

    ✨ Implement annotation feature for EPUB reader
@nwingt nwingt requested a review from Copilot February 26, 2026 10:08
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 6 comments.

return annotation
}

async function saveAnnotation(annotationId: string, data: AnnotationCreateData): Promise<Annotation | null> {
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race condition potential: If saveAnnotation is called while a previous fetchAnnotations is still in progress (via fetchPromise), the local annotation will be removed on line 56 but the fetch might complete afterwards and not include the new annotation. This could lead to a lost annotation in the UI. Consider checking if a fetch is in progress before removing the annotation, or handle this case explicitly.

Suggested change
async function saveAnnotation(annotationId: string, data: AnnotationCreateData): Promise<Annotation | null> {
async function saveAnnotation(annotationId: string, data: AnnotationCreateData): Promise<Annotation | null> {
// Ensure any in-flight fetchAnnotations completes before we mutate annotations
if (fetchPromise.value) {
await fetchPromise.value
}

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +90
catch (error) {
if (error instanceof H3Error && error.statusCode === 404) {
throw error
}
console.error(`Failed to update annotation ${annotationId}:`, error)
throw createError({
statusCode: 500,
message: 'FAILED_TO_UPDATE_ANNOTATION',
})
}
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent error handling: The error handling here wraps specific error types (H3Error with 404) but re-throws them, which is correct. However, other endpoints like index.post.ts (lines 99-105) check for specific gRPC status codes. Consider documenting the error handling patterns or creating a shared error handling utility to ensure consistency across all annotation endpoints.

Copilot uses AI. Check for mistakes.
Comment on lines +1306 to +1309
setTimeout(() => {
editingAnnotation.value = null
isNewAnnotation.value = false
}, 300)
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modal state timing: The modal close and state cleanup use a 300ms timeout (lines 1306-1309, 1334-1337) to wait for the modal close animation. This hardcoded delay could cause issues if the modal's animation duration changes. Consider using a CSS transition event listener or defining the animation duration as a shared constant to ensure the timing stays synchronized.

Copilot uses AI. Check for mistakes.
Comment on lines +799 to +821
if (removeMouseUpListener) {
removeMouseUpListener()
}
removeMouseUpListener = useEventListener(view.window, 'mouseup', (event: MouseEvent) => {
// Delay for window.getSelection() reflects the final selection state
setTimeout(() => {
handleTextSelection(event, view.window)
}, 10)
})

if (removeTouchEndListener) {
removeTouchEndListener()
}
removeTouchEndListener = useEventListener(view.window, 'touchend', (event: TouchEvent) => {
// Delay for touch selection to allow the browser's native selection UI (drag handles) to stabilize
setTimeout(() => {
const touch = event.changedTouches[0]
if (touch) {
const mouseEvent = { clientX: touch.clientX, clientY: touch.clientY } as MouseEvent
handleTextSelection(mouseEvent, view.window)
}
}, 300)
})
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory management: The cleanup in onBeforeUnmount is good, but the removeMouseUpListener and removeTouchEndListener are added in the displayed event handler (lines 799-821) which fires for each page/section loaded. If the user navigates through multiple pages before unmounting, multiple listeners could be registered without cleanup. The current implementation only stores the latest cleanup function, so previous listeners may leak. Consider removing the old listener before adding a new one, e.g., if (removeMouseUpListener) removeMouseUpListener() before line 802.

Copilot uses AI. Check for mistakes.
williamchong pushed a commit that referenced this pull request Feb 26, 2026
commit 959d68f
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 17:35:05 2026 +0800

    🎨 Update unused function param name

commit ff39b68
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:51:03 2026 +0800

    🎨 Use setHeaders instead of setResponseHeader

commit 2745979
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:38:10 2026 +0800

    🚸 Prevent system menu blocking annotation menu

commit 9d36efc
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:37:56 2026 +0800

    🐛 Fix annotation modal open when saving failed

commit ab1ad96
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:33 2026 +0800

    🎨 Sanitize annotations export filename

commit 75f7eef
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:06 2026 +0800

    🎨 Use UUID for temp annotation

commit e2537e3
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:31:51 2026 +0800

    🎨 Prevent memory leak

commit 69bfe0b
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:29:49 2026 +0800

    🥅 Guard annotation navigation

commit 511a24e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:20:53 2026 +0800

    🎨 Ensures annotations re-rendered when update

commit 11a5734
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:44:15 2026 +0800

    🔒 Truncate annotation text to max length on client side

commit f6b262c
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:22:44 2026 +0800

    🚸 Improve annotation UX

commit a208d2e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 23:34:22 2026 +0800

    🐛 Fix EventListener type mismatch in annotation highlight callback

commit a360ab4
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 10:30:29 2026 +0800

    🎨 Use typed Firestore collection

commit 50f1949
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 12 22:52:15 2026 +0800

    ✨ Support annotations export

commit b5e85f8
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Tue Jan 27 15:41:25 2026 +0800

    ✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 26, 2026
commit 959d68f
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 17:35:05 2026 +0800

    🎨 Update unused function param name

commit ff39b68
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:51:03 2026 +0800

    🎨 Use setHeaders instead of setResponseHeader

commit 2745979
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:38:10 2026 +0800

    🚸 Prevent system menu blocking annotation menu

commit 9d36efc
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:37:56 2026 +0800

    🐛 Fix annotation modal open when saving failed

commit ab1ad96
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:33 2026 +0800

    🎨 Sanitize annotations export filename

commit 75f7eef
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:06 2026 +0800

    🎨 Use UUID for temp annotation

commit e2537e3
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:31:51 2026 +0800

    🎨 Prevent memory leak

commit 69bfe0b
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:29:49 2026 +0800

    🥅 Guard annotation navigation

commit 511a24e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:20:53 2026 +0800

    🎨 Ensures annotations re-rendered when update

commit 11a5734
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:44:15 2026 +0800

    🔒 Truncate annotation text to max length on client side

commit f6b262c
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:22:44 2026 +0800

    🚸 Improve annotation UX

commit a208d2e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 23:34:22 2026 +0800

    🐛 Fix EventListener type mismatch in annotation highlight callback

commit a360ab4
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 10:30:29 2026 +0800

    🎨 Use typed Firestore collection

commit 50f1949
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 12 22:52:15 2026 +0800

    ✨ Support annotations export

commit b5e85f8
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Tue Jan 27 15:41:25 2026 +0800

    ✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 26, 2026
commit 959d68f
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 17:35:05 2026 +0800

    🎨 Update unused function param name

commit ff39b68
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:51:03 2026 +0800

    🎨 Use setHeaders instead of setResponseHeader

commit 2745979
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:38:10 2026 +0800

    🚸 Prevent system menu blocking annotation menu

commit 9d36efc
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:37:56 2026 +0800

    🐛 Fix annotation modal open when saving failed

commit ab1ad96
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:33 2026 +0800

    🎨 Sanitize annotations export filename

commit 75f7eef
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:06 2026 +0800

    🎨 Use UUID for temp annotation

commit e2537e3
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:31:51 2026 +0800

    🎨 Prevent memory leak

commit 69bfe0b
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:29:49 2026 +0800

    🥅 Guard annotation navigation

commit 511a24e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:20:53 2026 +0800

    🎨 Ensures annotations re-rendered when update

commit 11a5734
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:44:15 2026 +0800

    🔒 Truncate annotation text to max length on client side

commit f6b262c
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:22:44 2026 +0800

    🚸 Improve annotation UX

commit a208d2e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 23:34:22 2026 +0800

    🐛 Fix EventListener type mismatch in annotation highlight callback

commit a360ab4
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 10:30:29 2026 +0800

    🎨 Use typed Firestore collection

commit 50f1949
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 12 22:52:15 2026 +0800

    ✨ Support annotations export

commit b5e85f8
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Tue Jan 27 15:41:25 2026 +0800

    ✨ Implement annotation feature for EPUB reader
williamchong pushed a commit that referenced this pull request Feb 26, 2026
commit 959d68f
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 17:35:05 2026 +0800

    🎨 Update unused function param name

commit ff39b68
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:51:03 2026 +0800

    🎨 Use setHeaders instead of setResponseHeader

commit 2745979
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:38:10 2026 +0800

    🚸 Prevent system menu blocking annotation menu

commit 9d36efc
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:37:56 2026 +0800

    🐛 Fix annotation modal open when saving failed

commit ab1ad96
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:33 2026 +0800

    🎨 Sanitize annotations export filename

commit 75f7eef
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:06 2026 +0800

    🎨 Use UUID for temp annotation

commit e2537e3
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:31:51 2026 +0800

    🎨 Prevent memory leak

commit 69bfe0b
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:29:49 2026 +0800

    🥅 Guard annotation navigation

commit 511a24e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:20:53 2026 +0800

    🎨 Ensures annotations re-rendered when update

commit 11a5734
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:44:15 2026 +0800

    🔒 Truncate annotation text to max length on client side

commit f6b262c
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:22:44 2026 +0800

    🚸 Improve annotation UX

commit a208d2e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 23:34:22 2026 +0800

    🐛 Fix EventListener type mismatch in annotation highlight callback

commit a360ab4
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 10:30:29 2026 +0800

    🎨 Use typed Firestore collection

commit 50f1949
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 12 22:52:15 2026 +0800

    ✨ Support annotations export

commit b5e85f8
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Tue Jan 27 15:41:25 2026 +0800

    ✨ Implement annotation feature for EPUB reader
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 1 comment.

@nwingt nwingt requested a review from Copilot February 26, 2026 14:54
nwingt added a commit that referenced this pull request Feb 26, 2026
commit 959d68f
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 17:35:05 2026 +0800

    🎨 Update unused function param name

commit ff39b68
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:51:03 2026 +0800

    🎨 Use setHeaders instead of setResponseHeader

commit 2745979
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 16:38:10 2026 +0800

    🚸 Prevent system menu blocking annotation menu

commit 9d36efc
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:37:56 2026 +0800

    🐛 Fix annotation modal open when saving failed

commit ab1ad96
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:33 2026 +0800

    🎨 Sanitize annotations export filename

commit 75f7eef
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 15:00:06 2026 +0800

    🎨 Use UUID for temp annotation

commit e2537e3
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:31:51 2026 +0800

    🎨 Prevent memory leak

commit 69bfe0b
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:29:49 2026 +0800

    🥅 Guard annotation navigation

commit 511a24e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 14:20:53 2026 +0800

    🎨 Ensures annotations re-rendered when update

commit 11a5734
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:44:15 2026 +0800

    🔒 Truncate annotation text to max length on client side

commit f6b262c
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 26 10:22:44 2026 +0800

    🚸 Improve annotation UX

commit a208d2e
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 23:34:22 2026 +0800

    🐛 Fix EventListener type mismatch in annotation highlight callback

commit a360ab4
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Wed Feb 25 10:30:29 2026 +0800

    🎨 Use typed Firestore collection

commit 50f1949
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Thu Feb 12 22:52:15 2026 +0800

    ✨ Support annotations export

commit b5e85f8
Author: Ng Wing Tat, David <i@ngwingt.at>
Date:   Tue Jan 27 15:41:25 2026 +0800

    ✨ Implement annotation feature for EPUB reader
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 7 comments.

Comment on lines +23 to +26
let body: AnnotationCreateData
try {
body = await readBody(event)
}
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handler types body as AnnotationCreateData but doesn’t import that type. If annotation types are module exports (as in shared/types/annotation.d.ts), this will fail typechecking. Import AnnotationCreateData (and any related types) explicitly or define them as ambient types under /types.

Copilot uses AI. Check for mistakes.
Comment on lines +49 to +55
const props = defineProps<{
annotations: Annotation[]
}>()

const emit = defineEmits<{
(e: 'navigate', annotation: Annotation): void
}>()
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component references Annotation and AnnotationColor in prop and function typing but doesn’t import them. Add explicit type imports from ~/shared/types/annotation (or declare these as ambient types under /types) to avoid TypeScript errors.

Copilot uses AI. Check for mistakes.
Comment on lines +97 to +107
const props = defineProps<{
annotation?: Annotation | null
text: string
initialColor: AnnotationColor
isNewAnnotation?: boolean
}>()

const emit = defineEmits<{
(e: 'save', data: { color: AnnotationColor, note: string }): void
(e: 'delete'): void
}>()
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component uses Annotation/AnnotationColor in props/emits typing without importing them. Unless these are ambient declarations, this will fail nuxt typecheck. Import the types from ~/shared/types/annotation or define them as ambient types under /types (consistent with other globally declared interfaces).

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +12
export default function useAnnotations(params: {
nftClassId: Ref<string> | ComputedRef<string> | string
}) {
const { loggedIn: hasLoggedIn } = useUserSession()
const nftClassId = computed(() => toValue(params.nftClassId))

const annotations = ref<Annotation[]>([])
const isLoading = ref(false)
const hasFetched = ref(false)
const fetchPromise = ref<Promise<void> | null>(null)
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This composable uses Annotation, AnnotationCreateData, and AnnotationUpdateData without importing them. Unless these are ambient/global types, this will break nuxt typecheck. Import the needed types from ~/shared/types/annotation, or provide a global types/annotation.d.ts ambient declaration that matches the rest of the repo’s type pattern.

Copilot uses AI. Check for mistakes.
Comment on lines +31 to +34
let body: AnnotationUpdateData
try {
body = await readBody(event)
}
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handler types body as AnnotationUpdateData but doesn’t import that type. Add an explicit import type { AnnotationUpdateData } from '~/shared/types/annotation' (or make the annotation types ambient under /types) so nuxt typecheck doesn’t fail.

Copilot uses AI. Check for mistakes.
Comment on lines 377 to 426
@@ -365,6 +411,20 @@ const isMobileTocOpen = computed({

const isPageLoading = ref(false)

const isAnnotationMenuVisible = ref(false)
const annotationMenuPosition = ref({ x: 0, y: 0, yBottom: 0 })
const selectedText = ref('')
const selectedCfi = ref('')
const selectedChapterTitle = ref('')
const isAnnotationModalOpen = ref(false)
const editingAnnotation = ref<Annotation | null>(null)
const isNewAnnotation = ref(false)
const pendingAnnotationColor = ref<AnnotationColor>('yellow')
const isAnnotationsListOpen = ref(false)
const isAnnotationClickInProgress = ref(false)
const pendingSavePromise = ref<Promise<Annotation | null> | null>(null)
const renderedHighlights = new Set<string>()
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page uses Annotation, AnnotationColor, and AnnotationCreateData types without importing them. Unless they are ambient/global, this will break typechecking. Import the types from ~/shared/types/annotation (preferred if keeping them as module exports), or move them to an ambient /types/annotation.d.ts to match the repo’s existing global-type convention.

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +15
const ANNOTATION_COLOR_RGB: Record<AnnotationColor, string> = {
yellow: '202, 138, 4',
red: '220, 38, 38',
green: '22, 163, 74',
blue: '37, 99, 235',
}

/**
* Valid annotation color values for validation
*/
export const ANNOTATION_COLORS = Object.keys(ANNOTATION_COLOR_RGB) as AnnotationColor[]

Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AnnotationColor is referenced but not imported or declared as an ambient type. As written, this will fail TypeScript typechecking unless AnnotationColor is globally declared elsewhere. Either (a) move the annotation types into /types/*.d.ts using declare type/interface (to match existing global type patterns), or (b) add an explicit import type { AnnotationColor } from '~/shared/types/annotation' (and similarly for other annotation types) and use that import consistently.

Copilot uses AI. Check for mistakes.
@williamchong williamchong merged commit dd25c88 into likecoin:develop Feb 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants