feat: Text box editor with OCR improvements#149
Draft
Gnathonic wants to merge 25 commits into
Draft
Conversation
Implements a dedicated editing interface for modifying text box positions, sizes, text content, and font sizes with automatic optimization. Core Features: - Dedicated edit page route (/[manga]/[volume]/edit/[pageIndex]) - Visual manipulation with 5 handles per selected box: - Move handle (top-left): Drag to reposition - Delete handle (top-right): Remove box - Clone handle (bottom-left): Duplicate and place - Resize handle (bottom-right): Adjust dimensions - Auto-size handle (right side): Automatically optimize font size Versioning System: - Added edited_pages field to VolumeData for non-destructive editing - Original mokuro data preserved in pages field - Reader automatically uses edited version via getCurrentPages() utility - Save edits to IndexedDB, export .mokuro JSON file UI/UX: - Zoom modes: Fit to Screen, Fit to Width, Original Size - Page navigation with unsaved changes warning - Real-time font size preview - Auto-size algorithm: increases until overflow, then decreases to fit - Text editing: Click selected box to edit content inline Entry Point: - Edit button added to QuickActions floating menu - Page selector modal for dual-page view - Seamless navigation between reader and editor Closes #145 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…tate Fixed DataCloneError that occurred when saving text box edits to IndexedDB. The issue was caused by attempting to store Svelte $state proxies and Dexie IndexedDB objects directly, which cannot be cloned by the structured clone algorithm. ## Changes - Changed from `structuredClone()` to `JSON.parse(JSON.stringify())` for cloning pages - Added serialization of `workingBlocks` before assignment to strip Svelte reactivity - Updated comments to clarify the serialization is needed for both IndexedDB objects and Svelte proxies ## Technical Details The error occurred in two places: 1. `currentPages` from Dexie had properties that couldn't be cloned 2. `workingBlocks` as a `$state` variable was wrapped in Svelte proxies JSON serialization strips all non-serializable properties and proxies, leaving only plain data that IndexedDB can store. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Added visual indicators and the ability to revert edits to original mokuro data. ## Changes **Visual Indicators:** - Added yellow pencil badge to VolumeItem component (both list and grid views) - Badge appears when a volume has edited pages - Uses `hasEdits()` utility to check for `edited_pages` field **Revert Functionality:** - Added "Revert to Original" button in EditToolbar - Button only appears when volume has edits - Shows confirmation dialog before reverting - Removes `edited_pages` field from database - Reloads page data to show original content - Shows success/error toasts **Component Updates:** - VolumeItem.svelte: Added `volumeHasEdits` state and pencil badge - EditToolbar.svelte: Added `hasEdits` prop and revert button - edit/+page.svelte: Added `volumeHasEdits` derived, `revertToOriginal()` function 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Added a comparison modal that displays original and edited versions side-by-side. ## Changes **Comparison Modal:** - Added "Compare" button in EditToolbar (purple, appears when volume has edits) - Modal shows original (left) and edited (right) versions side-by-side - Color-coded borders: blue for original boxes, green for edited boxes - Full-size view with scrollable containers - Maximum width set to 90vw for better visibility **Technical Details:** - Added `originalPageData` derived value using `getOriginalPages()` - Added `showCompareModal` state for modal visibility - Modal renders both versions with identical styling to editor - Shows text boxes with proper font sizes, writing modes, and line breaks **Component Updates:** - EditToolbar.svelte: Added Compare button and onCompare prop - edit/+page.svelte: Added comparison modal with side-by-side layout This helps users visualize their changes before saving or reverting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Changed from ArrowRotateBackwardSolid (doesn't exist) to UndoOutline. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Removed the comparison modal and added the ability to create new text boxes. ## Changes **Add Textbox Button:** - Added purple "Add Textbox" button in EditToolbar - Creates new empty text box in center of page - Default size: 200x100px, font size 20px - Auto-selects new box for immediate editing - Marks page as having unsaved changes **Removed Features:** - Removed comparison modal (original vs edited view) - Removed onCompare callback and related code - Removed unused imports (getOriginalPages, Modal) **Component Updates:** - EditToolbar.svelte: Replaced Compare button with Add Textbox - edit/+page.svelte: Added addTextbox() function, removed compare modal This makes it easier to add custom text annotations to manga pages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fixed two issues: 1. Changed PlusSolid to CirclePlusSolid (correct Flowbite icon name) 2. Added separate toast for revert operations to avoid confusion ## Changes - EditToolbar.svelte: Use CirclePlusSolid instead of PlusSolid - edit/+page.svelte: Added showRevertSuccess state and toast - Revert now shows "Reverted to original" instead of "Edits saved successfully" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Implemented automatic font sizing during resize operations and removed the redundant manual auto-size button. ## Changes **Auto-resize during drag:** - Font size now automatically adjusts as you resize a text box - Throttled to every 10th frame for smooth performance - Final auto-size runs when resize completes for perfect fitting - Uses fast overflow detection to increase/decrease font size **Removed manual button:** - Removed auto-size button (now redundant) - Removed TextSizeOutline icon import - Removed handle-font-auto CSS styles - Updated resize handle tooltip to indicate auto-sizing **Bug fixes:** - Added data-block-index attribute for DOM queries - Added text-container class for overflow detection - Fixed page navigation not updating text boxes - Added $effect to reload workingBlocks on page change - Removed transition-all for instant position updates - Fixed Modal import that was accidentally removed - Fixed toast showing on page load with isMounted guard **Technical improvements:** - Used JSON serialization instead of structuredClone for Svelte state - Throttled auto-size to prevent blocking resize operations - requestAnimationFrame for non-blocking font updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Resolved merge conflicts: - QuickActions.svelte: Migrated from SpeedDial to custom buttons + added edit feature - Reader.svelte: Added editor props (currentPage, showSecondPage) - VolumeItem.svelte: Combined edits badge with image-only badge Updated editor components for Flowbite v1: - EditToolbar.svelte: on:change → onchange for Select - Edit page: on:click → onclick for Button, updated Toast API to use snippets and conditional rendering
- Pass `seriesId` and `volumeId` explicitly from Reader to QuickActions component - Update QuickActions to use passed props instead of reading from $page.params - Fixes issue where editor URL would resolve to /undefined/undefined/edit/... due to stale page parameters during component initialization
- Update `loadVolumeData` to fetch from `volume_ocr` and `volume_files` tables separately, as `volumes_data` does not exist in V3 schema - Manually construct `VolumeData` object from separate table results - Update `saveEdits` and `revertToOriginal` to target `volume_ocr` table - Add `edited_pages` field to `VolumeOCR` type definition - Refactor data loading to use `$effect` instead of `onMount` to prevent race conditions when route parameters change
Status: Functional but needs integration review, reader currently not using changed pages Block-level (verbatim port): - OcrBlock.svelte: Block drag, resize, child line orchestration - OcrLine.svelte: Line editing with split/merge/navigation, double-click to edit - ResizeHandles.svelte: 8-point resize controls with hover/touch visibility - TouchToggle.svelte: Mobile-friendly hover/touch visibility wrapper - ocrMath utilities: getImageDeltas, smartResizeFont, ligaturize - Pointer events with manual delta calculation for consistent touch behavior Canvas-level (adapted for mokuro-reader): - EditCanvas.svelte: Integrated OcrState, replaced EditableBox architecture - OcrState.svelte.ts: Adapted for manual CSS scale (no Panzoom instance) - Focus/dirty state propagation via callbacks instead of stores - workingBlocks bound directly to canvas instead of CRUD callbacks - Exposed deleteFocusedBlock() and addTextboxToCenter() methods Toolbar updates: - Delete button with selection state tracking - Responsive layout (hide labels on small screens) - Button groups: block actions vs page actions - Unsaved changes indicator - Tooltips for icon-only buttons
…background - Clicks on blocks or lines focuses the block - Clicks on background remove focus for all
- Fetch edited_pages in catalog/index.ts
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
vncthar
pushed a commit
to vncthar/mokuro-reader
that referenced
this pull request
Mar 10, 2026
…tbox-resize feat: Lazy-load textbox resize calculations on hover
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Combines the text box editor feature with OCR editing improvements from @nguyenston.
Original text-box-editor features:
/[manga]/[volume]/edit/[pageIndex]edited_pagesfieldOCR improvements by @nguyenston:
Credits
This PR incorporates work from:
🤖 Generated with Claude Code