feat(reader): note length counter and save guards in the reader UI
Oversized notes previously failed only at save time, surfacing the raw backend validator error to the reader. The reader now handles the limit inline and keeps oversized input editable: - Live character counter under both note textareas (annotations drawer "Add a note" and the selection popover note editor), formatted "12,345/100,000" — muted normally, red once over - Pasting is never truncated; the full text stays in the textarea so the reader can shrink it however they see fit - The three save actions (Add Note, Highlight with note, Save note) disable while over the limit, with a toast fallback in addNote / createHighlight / saveHighlightChanges so the guard holds even outside the disabled-button path - noteMaxLength mirrors the server-side cap (100,000, see internal/handlers/media.go) so client and server stay linked Also truncate note rows in the drawer list — highlight rows already truncated, but a long note previously stretched the drawer body. The resize handle needed no work: .reader-note-input already ships resize: vertical in the compiled CSS; style.css is rebuilt only for the new disabled:* utility classes.
This commit is contained in:
+20
-3
@@ -179,10 +179,17 @@ templ Reader(user User, metadata ReaderMetadata) {
|
||||
class="reader-note-input"
|
||||
placeholder="Note…"
|
||||
></textarea>
|
||||
<div
|
||||
class="text-xs mt-0.5 text-right"
|
||||
x-show="selectionPopover.note.length > 0"
|
||||
:style="noteOverLimit(selectionPopover.note) ? 'color: #f87171;' : 'color: var(--text-secondary);'"
|
||||
x-text="noteCountLabel(selectionPopover.note)"
|
||||
></div>
|
||||
<div class="flex gap-2 mt-1">
|
||||
<button
|
||||
type="button"
|
||||
class="flex-1 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700"
|
||||
class="flex-1 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
:disabled="noteOverLimit(selectionPopover.note)"
|
||||
@click="selectionPopover.mode === 'create' ? createHighlight(selectionPopover.color) : saveHighlightChanges()"
|
||||
x-text="selectionPopover.mode === 'create' ? 'Highlight with note' : 'Save note'"
|
||||
>Save</button>
|
||||
@@ -651,14 +658,24 @@ templ ReaderAnnotationsDrawer() {
|
||||
class="reader-note-input"
|
||||
placeholder="Add a note at the current position…"
|
||||
></textarea>
|
||||
<button @click="addNote(newNoteText); newNoteText = ''" class="w-full py-1.5 mt-1 mb-3 text-sm bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||
<div
|
||||
class="text-xs mt-0.5 text-right"
|
||||
x-show="newNoteText.length > 0"
|
||||
:style="noteOverLimit(newNoteText) ? 'color: #f87171;' : 'color: var(--text-secondary);'"
|
||||
x-text="noteCountLabel(newNoteText)"
|
||||
></div>
|
||||
<button
|
||||
@click="addNote(newNoteText); newNoteText = ''"
|
||||
:disabled="noteOverLimit(newNoteText)"
|
||||
class="w-full py-1.5 mt-1 mb-3 text-sm bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
+ Add Note
|
||||
</button>
|
||||
<div class="space-y-2">
|
||||
<template x-for="note in noteItems" :key="note.id">
|
||||
<div class="reader-hl-row group">
|
||||
<a href="#" @click.prevent="closeDrawers()" class="flex-1 min-w-0 block py-2 px-2 rounded hover:bg-gray-700">
|
||||
<span class="block text-sm" x-text="note.content"></span>
|
||||
<span class="block text-sm truncate" x-text="note.content"></span>
|
||||
<span class="block text-xs mt-0.5 truncate" style="color: var(--text-secondary)" x-text="note.positionLabel"></span>
|
||||
</a>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user