commitf1901a2e56Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 27 18:23:27 2025 +0000 revert lint commit09b0fbefcdAuthor: Reece <reece@stirlingpdf.com> Date: Mon Oct 27 15:47:38 2025 +0000 Hide file names in posthog commit3497ccd7bdAuthor: Reece <reece@stirlingpdf.com> Date: Mon Oct 27 12:45:31 2025 +0000 remove page break settings modal commit5e27dc88f8Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 27 12:37:00 2025 +0000 retain interleaving commitb276eb5b68Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 27 11:32:31 2025 +0000 Lint commitaec1f97ff8Author: Reece <reece@stirlingpdf.com> Date: Sat Oct 25 14:19:32 2025 +0100 - commitfbe2dc2958Author: Reece <reece@stirlingpdf.com> Date: Sat Oct 25 13:06:10 2025 +0100 Fixed file reordering placeholder commitaaae81c68eAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 15:57:30 2025 +0100 - commit3aa77819f2Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 15:54:30 2025 +0100 - commit28dab07870Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 15:51:37 2025 +0100 - commited6199de61Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 15:51:29 2025 +0100 lint and revert onboarding commit4d59ebfb2aAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 15:27:44 2025 +0100 fixed drag and drop when some files aren't selected in context commitea4f37cccfAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 15:06:21 2025 +0100 Merge history change commitc25131ae9bAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 14:48:14 2025 +0100 lint commit25df9410cdMerge:494f92421848ff9688Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 14:33:27 2025 +0100 Merge branch 'V2' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/selected-pageeditor commit494f92421fAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 13:28:50 2025 +0100 Enhance drag-and-drop functionality with new drop hint resolution and target index calculation; refactor file color mapping in PageEditor and implement dropdown state management for improved file handling. commiteef5dce849Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 24 11:33:31 2025 +0100 Drag and drop improvements basic box select commitddefe81082Author: Reece <reece@stirlingpdf.com> Date: Thu Oct 23 20:46:58 2025 +0100 Enhance DragDropGrid and PageEditor with improved undo manager functionality and scroll handling during drag operations commitbe037b727fAuthor: Reece <reece@stirlingpdf.com> Date: Thu Oct 23 18:15:37 2025 +0100 File reorder logic commit7a56f0504eAuthor: Reece <reece@stirlingpdf.com> Date: Tue Oct 21 17:35:55 2025 +0100 Refactor file handling to support StirlingFileStubs and improve drag-and-drop functionality commitf7c9855489Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 21:45:00 2025 +0100 glow scaling commit36a358f907Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 21:25:44 2025 +0100 Visual tweaks commit0bcb1810d6Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 21:08:18 2025 +0100 tweak commitaee535214dAuthor: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 20:55:45 2025 +0100 Pretty lights commit6d3154a7aeAuthor: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 20:44:48 2025 +0100 Update top bar controls visually commit658ce2dab9Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 18:45:14 2025 +0100 add file commit15df5cf168Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 18:05:55 2025 +0100 - commit23d7f38100Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 17:24:16 2025 +0100 lint commit472fc2939eAuthor: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 15:56:54 2025 +0100 lint 2 commita21047e8b0Merge:8ee03fa1c3e23dc59bAuthor: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Mon Oct 20 15:52:23 2025 +0100 Merge branch 'V2' into feature/v2/selected-pageeditor commit8ee03fa1c6Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 15:50:14 2025 +0100 Lint commita22913e1e4Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 14:16:41 2025 +0100 page editor fixes post merge commitb3c0c69a7cMerge:2289080f93e6236d95Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 20 13:42:08 2025 +0100 Merge branch 'V2' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/selected-pageeditor commit2289080f9cAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 17 16:55:29 2025 +0100 remove buttons commita5ec62fa08Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 17 15:24:05 2025 +0100 Performance improvements commite7f7b7e201Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 17 14:15:21 2025 +0100 improved commit74e8388bceAuthor: Reece <reece@stirlingpdf.com> Date: Wed Oct 15 21:33:54 2025 +0100 Working mostly commite7c6db082cAuthor: Reece <reece@stirlingpdf.com> Date: Wed Oct 15 16:31:30 2025 +0100 Rejig arrays commit05a7161412Author: Reece <reece@stirlingpdf.com> Date: Wed Oct 15 00:01:30 2025 +0100 Structural tweaks commit39267e795cAuthor: Reece <reece@stirlingpdf.com> Date: Tue Oct 14 12:41:50 2025 +0100 Reworked page editor - dirty commit commit6acce968a5Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 19:32:41 2025 +0100 fix 2 commit0722ecc6c4Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 19:27:15 2025 +0100 fix commit3597a8b7bdAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 19:16:04 2025 +0100 Initial set up commitc260394b95Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 17:15:07 2025 +0100 Cleanup commit93fcfb280aAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 17:09:36 2025 +0100 Remove logs tweak visuals, use fit text component commit69cb8e7aecAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 16:54:05 2025 +0100 Fix signwith tab based system commit8e8e06628eAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 15:57:41 2025 +0100 Nav based file select commit5d3710260fAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 13:37:52 2025 +0100 Lint commitad8789d82aAuthor: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 13:35:18 2025 +0100 remove file that came from nowhere commit749966a197Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 13:30:15 2025 +0100 Remove mantine theme commitd9e429aa3aMerge:ad0b6cf2db695e3900Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 13:00:56 2025 +0100 Merge branch 'V2' of https://github.com/Stirling-Tools/Stirling-PDF into feature/V2/ViewerTabs commitad0b6cf2d6Author: Reece <reece@stirlingpdf.com> Date: Fri Oct 10 12:55:03 2025 +0100 Viewer tabs, embed update and layout fixes commitb63f2c16a2Author: Reece <reece@stirlingpdf.com> Date: Wed Oct 8 15:12:39 2025 +0100 Remove unused legacy text signing Linting errors commitedcc788d1aMerge:5b47ab5bbfdba336c0Author: Reece <reece@stirlingpdf.com> Date: Wed Oct 8 15:02:39 2025 +0100 Merge branch 'feature/v2/improve-sign' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/improve-sign commit5b47ab5bbfAuthor: Reece <reece@stirlingpdf.com> Date: Wed Oct 8 15:02:33 2025 +0100 Remove debug logs commitfdba336c05Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Wed Oct 8 14:57:29 2025 +0100 Update frontend/src/components/annotation/shared/DrawingCanvas.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> commit5db6b85fb9Merge:70d941a4013e88943bAuthor: Reece <reece@stirlingpdf.com> Date: Wed Oct 8 14:56:10 2025 +0100 Merge branch 'feature/v2/improve-sign' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/improve-sign commit70d941a400Author: Reece <reece@stirlingpdf.com> Date: Wed Oct 8 14:55:43 2025 +0100 translations commit13e88943b7Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Wed Oct 8 14:55:04 2025 +0100 Update frontend/src/components/tools/sign/SignSettings.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> commit339e5cfb65Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Wed Oct 8 14:54:31 2025 +0100 Update frontend/src/contexts/ViewerContext.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> commit10944d9d57Author: Reece <reece@stirlingpdf.com> Date: Wed Oct 8 14:45:39 2025 +0100 Remove debug logging commit0c9f460fb6Author: Reece <reece@stirlingpdf.com> Date: Wed Oct 8 14:02:43 2025 +0100 Remove arbitrary timers commitfa6e01b46eAuthor: Reece <reece@stirlingpdf.com> Date: Wed Oct 8 12:26:34 2025 +0100 Clean up commit23f85d7267Author: Reece <reece@stirlingpdf.com> Date: Tue Oct 7 22:40:58 2025 +0100 tweaks commitf6290c0238Author: Reece <reece@stirlingpdf.com> Date: Tue Oct 7 21:52:40 2025 +0100 - Refactored signature saving process commit991be9ffa2Author: Reece <reece@stirlingpdf.com> Date: Tue Oct 7 21:38:07 2025 +0100 Add text color and font size options to signature settings and API commit07bf79f3eeAuthor: Reece <reece@stirlingpdf.com> Date: Tue Oct 7 14:54:14 2025 +0100 Improved canvas mode with signaturepad.js commit3a0acd0a21Author: Reece <reece@stirlingpdf.com> Date: Tue Oct 7 12:56:12 2025 +0100 Single canvas commitfff637286fAuthor: Reece <reece@stirlingpdf.com> Date: Tue Oct 7 12:08:32 2025 +0100 Clean up annotation layer and signature API - Remove duplicate imports in LocalEmbedPDF - Remove duplicate setAnnotations state declaration - Rename enableSignature prop to enableAnnotations for consistency - Remove debug console.log statements from SignatureAPIBridge - Remove async image preloading wrapper (was debugging code) - Clean up formatting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> commit8f94c8f57eMerge:708a296f82a29bda34Author: Reece <reece@stirlingpdf.com> Date: Mon Oct 6 22:25:30 2025 +0100 Merge branch 'V2' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/improve-sign commit708a296f8dAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 19:14:40 2025 +0100 Auto update canvas signature commitb486d1270eAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 19:03:24 2025 +0100 Fix flicker on apply commit80faf0bc1eAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 18:55:09 2025 +0100 - commit6555a9554aAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 18:53:16 2025 +0100 Fix even more linting errors (Thanks James) commitfdee719c89Merge:1be48c276fd9fb9b97Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 18:14:42 2025 +0100 Merge branch 'feature/v2/sign' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/sign commit1be48c276bAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 18:12:13 2025 +0100 fix text infinite loop commit2b6b7a8e1dAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 18:04:01 2025 +0100 better error handling and killing logs commitfd9fb9b972Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Fri Sep 26 17:58:52 2025 +0100 Update frontend/src/hooks/tools/sign/useSignParameters.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> commitd8d6197008Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 17:48:41 2025 +0100 fix page count issue commit1edd133e09Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 17:31:44 2025 +0100 license checker use commonJS commit8685bf2a7cAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 17:26:19 2025 +0100 gap commit36475069deAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 17:23:16 2025 +0100 lint fix commit3aa8572c9eAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 17:16:17 2025 +0100 Fix suggestions commit2e2d8477b9Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 17:01:06 2025 +0100 Clean up commit90880eddf9Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Fri Sep 26 16:51:19 2025 +0100 Update docker/frontend/nginx.conf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> commit31fd6886dcMerge:3fdbf425babc0988fdAuthor: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Fri Sep 26 16:40:34 2025 +0100 Merge branch 'V2' into feature/v2/sign commit3fdbf425b4Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 16:39:38 2025 +0100 Fix lintineg errors commit50e60d4972Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 16:27:52 2025 +0100 Simple export block commita22330ebf4Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 16:09:20 2025 +0100 Only flatten current annotations commit172f622c5fMerge:cfd00b2c7d82b958d9Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 15:10:54 2025 +0100 Merge branch 'feature/v2/sign' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/sign commitcfd00b2c71Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 15:10:47 2025 +0100 Render signature to pdf commitd82b958d9fMerge:c94ee388f0bdc6466cAuthor: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Fri Sep 26 12:53:54 2025 +0100 Merge branch 'V2' into feature/v2/sign commitc94ee388fcAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 12:47:32 2025 +0100 Restructure and bug fix commitaa5333dcd9Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 03:23:59 2025 +0100 Change to button based placement to avoid performance issue on canvas commita8265efff4Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 03:19:05 2025 +0100 Improved performance commitb9b425aba0Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 02:18:47 2025 +0100 Fix undo/redo commit51caad636cAuthor: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 01:51:17 2025 +0100 Reduce logs commit023fd43b72Author: Reece <reece@stirlingpdf.com> Date: Fri Sep 26 01:49:33 2025 +0100 Save file commita8a0808274Author: Reece <reece@stirlingpdf.com> Date: Thu Sep 25 09:46:20 2025 +0100 history tweaks commit3d2607f72aAuthor: Reece <reece@stirlingpdf.com> Date: Wed Sep 24 19:01:36 2025 +0100 fixes commitf9542a9257Merge:a12e45757963787316Author: Reece <reece@stirlingpdf.com> Date: Wed Sep 24 18:35:16 2025 +0100 Merge branch 'feature/v2/exportpdf' into feature/v2/sign commit963787316aAuthor: Reece <reece@stirlingpdf.com> Date: Wed Sep 24 17:42:58 2025 +0100 Export with embedpdf commita12e457577Author: Reece Browne <reecebrowne1995@gmail.com> Date: Wed Sep 24 14:58:10 2025 +0100 Add undo/redo functionality and refactor signature settings UI - Introduced HistoryAPIBridge for managing undo/redo actions. - Updated SignSettings component to include undo/redo buttons. - Refactored signature type selection to use Tabs for better UI. - Enhanced SignatureAPIBridge to store image data for annotations. - Integrated history management into SignatureContext for state handling. commitbac61c7e9eAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Tue Sep 23 18:16:21 2025 +0100 Delete signature commitfc2f34ee15Author: Reece Browne <reecebrowne1995@gmail.com> Date: Tue Sep 23 17:18:39 2025 +0100 fix add image commitd9798badaeAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Tue Sep 23 14:06:41 2025 +0100 Fix sidebar refresh. Updated UI commitefc0c1aab3Author: Reece Browne <reecebrowne1995@gmail.com> Date: Tue Sep 23 12:24:58 2025 +0100 text and improved drawing commit10672403c9Author: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 22 14:14:35 2025 +0100 Colours on document draw + translations commit32fed96aa7Author: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 22 14:03:49 2025 +0100 Canvas and dosument draw split, drawing improvements commita70472b172Author: Reece Browne <reecebrowne1995@gmail.com> Date: Sat Sep 20 01:59:04 2025 +0100 Initial set up commit3b87ca0c3cMerge:0e1da982b6172351eeAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 19 11:38:58 2025 +0100 Merge branch 'feature/v2/embed-pdf' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/embed-pdf commit0e1da982b6Author: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 19 11:38:53 2025 +0100 Fix vite commit6172351eedMerge:1174b6a4dae7be50ecAuthor: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Fri Sep 19 11:23:28 2025 +0100 Merge branch 'V2' into feature/v2/embed-pdf commit1174b6a4daMerge:a970c44d021a2433ddAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 19 11:16:22 2025 +0100 Merge branch 'feature/v2/embed-pdf' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/embed-pdf commita970c44d03Author: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 19 11:14:58 2025 +0100 improvements commitb574cef54aAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 19 10:48:29 2025 +0100 improvements commit21a2433dd8Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Thu Sep 18 13:14:44 2025 +0100 Remove marginTop style from Workbench component commit07cc250176Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Thu Sep 18 13:12:58 2025 +0100 Remove comment regarding EmbedPDF import Removed comment about dynamic import of EmbedPDF. commitdc71b3007bAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 18 12:32:42 2025 +0100 clean up commit1598057ed0Author: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 18 08:44:57 2025 +0100 Tweaks commit312fc2d615Author: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 18 02:14:31 2025 +0100 Clean up commit72375d89d1Merge:a990ecc027ff1c66d0Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Thu Sep 18 01:53:59 2025 +0100 Merge branch 'V2' into feature/v2/embed-pdf commita990ecc02aMerge:da6ecc661b51c2e42aAuthor: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Thu Sep 18 01:53:47 2025 +0100 Merge branch 'V2' into feature/v2/embed-pdf commitda6ecc6619Author: Reece Browne <reecebrowne1995@gmail.com> Date: Wed Sep 17 14:35:44 2025 +0100 Fix scroll page identification commitdac176f0c6Author: Reece Browne <reecebrowne1995@gmail.com> Date: Wed Sep 17 12:07:44 2025 +0100 Fix colours commit41e5a7fbd6Author: Reece Browne <reecebrowne1995@gmail.com> Date: Wed Sep 17 12:00:20 2025 +0100 Restructure to avoid global variables fix zoom commitb81ed9ec2eMerge:9b5c50db081c5d8ff4Author: Reece Browne <reecebrowne1995@gmail.com> Date: Tue Sep 16 19:37:50 2025 +0100 Merge branch 'feature/v2/embed-pdf' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/embed-pdf commit9b5c50db07Author: Reece Browne <reecebrowne1995@gmail.com> Date: Tue Sep 16 19:36:36 2025 +0100 Improved Structure with context at root commit81c5d8ff46Author: James Brunton <james@stirlingpdf.com> Date: Tue Sep 16 16:06:40 2025 +0100 Potential fix for mime type issues commita67f5199d3Author: James Brunton <james@stirlingpdf.com> Date: Tue Sep 16 16:06:27 2025 +0100 Improvements for scroll gestures commit3755bfde34Author: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 18:20:11 2025 +0100 Set zoom to 140% commit2834eec3beMerge:19d7111cad89e1b5b1Author: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 17:31:06 2025 +0100 Merge branch 'feature/v2/embed-pdf' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/embed-pdf commitd89e1b5b1eMerge:5d7fb638aa57373b96Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Mon Sep 15 17:27:51 2025 +0100 Merge branch 'V2' into feature/v2/embed-pdf commit19d7111cabAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 17:27:22 2025 +0100 Remove unused code commitca9d7ef465Author: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 17:03:52 2025 +0100 Remove unused code commitfad4f84c9cAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 16:53:41 2025 +0100 translations commit35863ac610Author: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 16:53:32 2025 +0100 remove select mode commitc17dd25069Author: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 16:05:19 2025 +0100 Rotate commit5d7fb638afMerge:2fb4710dd7dad484aaAuthor: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Mon Sep 15 15:31:45 2025 +0100 Merge branch 'V2' into feature/v2/embed-pdf commit2fb4710dd7Merge:85a74c1d4cfdb6eaa1Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Mon Sep 15 13:34:00 2025 +0100 Merge branch 'V2' into feature/v2/embed-pdf commit85a74c1d46Merge:21a93d6ca9599bca8aAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 13:33:45 2025 +0100 Merge branch 'feature/v2/embed-pdf' of https://github.com/Stirling-Tools/Stirling-PDF into feature/v2/embed-pdf commit21a93d6cacAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Mon Sep 15 13:33:39 2025 +0100 Context based right rail controls for viewer commit9599bca8a9Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com> Date: Mon Sep 15 12:37:07 2025 +0100 Update frontend/src/components/viewer/ThumbnailSidebar.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> commit1709ca9049Author: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 12 16:38:29 2025 +0100 Rems commit18e4e03220Author: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 12 16:26:05 2025 +0100 rename APIBridge commit9901771572Author: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 12 16:19:07 2025 +0100 improve search commit514956570cAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 12 15:06:06 2025 +0100 pan state improvements commit423617db52Author: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 12 14:21:31 2025 +0100 thumbnail sidebar commit143f0c5031Author: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 12 01:56:51 2025 +0100 search pdf commit368e9801a1Author: Reece Browne <reecebrowne1995@gmail.com> Date: Fri Sep 12 00:35:27 2025 +0100 Zoom with wheel and +/- commitafc9ca5858Author: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 11 23:52:38 2025 +0100 spread/multipage commit8815575124Author: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 11 22:51:10 2025 +0100 pan commitfb9b01f53bAuthor: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 11 20:07:43 2025 +0100 improved scaling and fix grey void commit93607937f6Author: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 11 19:38:04 2025 +0100 selection also commit687ab39286Author: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 11 19:36:44 2025 +0100 Text selection commit83a3222cf6Author: Reece Browne <reecebrowne1995@gmail.com> Date: Thu Sep 11 19:08:44 2025 +0100 Set up
647 lines
18 KiB
TypeScript
647 lines
18 KiB
TypeScript
import React, { createContext, useContext, useState, ReactNode, useRef, useMemo, useCallback } from 'react';
|
|
import { SpreadMode } from '@embedpdf/plugin-spread/react';
|
|
import { useNavigation } from '@app/contexts/NavigationContext';
|
|
|
|
// Bridge API interfaces - these match what the bridges provide
|
|
interface ScrollAPIWrapper {
|
|
scrollToPage: (params: { pageNumber: number }) => void;
|
|
scrollToPreviousPage: () => void;
|
|
scrollToNextPage: () => void;
|
|
}
|
|
|
|
interface ZoomAPIWrapper {
|
|
zoomIn: () => void;
|
|
zoomOut: () => void;
|
|
toggleMarqueeZoom: () => void;
|
|
requestZoom: (level: number) => void;
|
|
}
|
|
|
|
interface PanAPIWrapper {
|
|
enable: () => void;
|
|
disable: () => void;
|
|
toggle: () => void;
|
|
}
|
|
|
|
interface SelectionAPIWrapper {
|
|
copyToClipboard: () => void;
|
|
getSelectedText: () => string | any;
|
|
getFormattedSelection: () => any;
|
|
}
|
|
|
|
interface SpreadAPIWrapper {
|
|
setSpreadMode: (mode: SpreadMode) => void;
|
|
getSpreadMode: () => SpreadMode | null;
|
|
toggleSpreadMode: () => void;
|
|
}
|
|
|
|
interface RotationAPIWrapper {
|
|
rotateForward: () => void;
|
|
rotateBackward: () => void;
|
|
setRotation: (rotation: number) => void;
|
|
getRotation: () => number;
|
|
}
|
|
|
|
interface SearchAPIWrapper {
|
|
search: (query: string) => Promise<any>;
|
|
clear: () => void;
|
|
next: () => void;
|
|
previous: () => void;
|
|
}
|
|
|
|
interface ThumbnailAPIWrapper {
|
|
renderThumb: (pageIndex: number, scale: number) => { toPromise: () => Promise<Blob> };
|
|
}
|
|
|
|
interface ExportAPIWrapper {
|
|
download: () => void;
|
|
saveAsCopy: () => { toPromise: () => Promise<ArrayBuffer> };
|
|
}
|
|
|
|
|
|
// State interfaces - represent the shape of data from each bridge
|
|
interface ScrollState {
|
|
currentPage: number;
|
|
totalPages: number;
|
|
}
|
|
|
|
interface ZoomState {
|
|
currentZoom: number;
|
|
zoomPercent: number;
|
|
}
|
|
|
|
interface PanState {
|
|
isPanning: boolean;
|
|
}
|
|
|
|
interface SelectionState {
|
|
hasSelection: boolean;
|
|
}
|
|
|
|
interface SpreadState {
|
|
spreadMode: SpreadMode;
|
|
isDualPage: boolean;
|
|
}
|
|
|
|
interface RotationState {
|
|
rotation: number;
|
|
}
|
|
|
|
interface SearchResult {
|
|
pageIndex: number;
|
|
rects: Array<{
|
|
origin: { x: number; y: number };
|
|
size: { width: number; height: number };
|
|
}>;
|
|
}
|
|
|
|
interface SearchState {
|
|
results: SearchResult[] | null;
|
|
activeIndex: number;
|
|
}
|
|
|
|
interface ExportState {
|
|
canExport: boolean;
|
|
}
|
|
|
|
// Bridge registration interface - bridges register with state and API
|
|
interface BridgeRef<TState = unknown, TApi = unknown> {
|
|
state: TState;
|
|
api: TApi;
|
|
}
|
|
|
|
/**
|
|
* ViewerContext provides a unified interface to EmbedPDF functionality.
|
|
*
|
|
* Architecture:
|
|
* - Bridges store their own state locally and register with this context
|
|
* - Context provides read-only access to bridge state via getter functions
|
|
* - Actions call EmbedPDF APIs directly through bridge references
|
|
* - No circular dependencies - bridges don't call back into this context
|
|
*/
|
|
interface ViewerContextType {
|
|
// UI state managed by this context
|
|
isThumbnailSidebarVisible: boolean;
|
|
toggleThumbnailSidebar: () => void;
|
|
|
|
// Annotation visibility toggle
|
|
isAnnotationsVisible: boolean;
|
|
toggleAnnotationsVisibility: () => void;
|
|
|
|
// Annotation/drawing mode for viewer
|
|
isAnnotationMode: boolean;
|
|
setAnnotationMode: (enabled: boolean) => void;
|
|
toggleAnnotationMode: () => void;
|
|
|
|
// Active file index for multi-file viewing
|
|
activeFileIndex: number;
|
|
setActiveFileIndex: (index: number) => void;
|
|
|
|
// State getters - read current state from bridges
|
|
getScrollState: () => ScrollState;
|
|
getZoomState: () => ZoomState;
|
|
getPanState: () => PanState;
|
|
getSelectionState: () => SelectionState;
|
|
getSpreadState: () => SpreadState;
|
|
getRotationState: () => RotationState;
|
|
getSearchState: () => SearchState;
|
|
getThumbnailAPI: () => ThumbnailAPIWrapper | null;
|
|
getExportState: () => ExportState;
|
|
|
|
// Immediate update callbacks
|
|
registerImmediateZoomUpdate: (callback: (percent: number) => void) => void;
|
|
registerImmediateScrollUpdate: (callback: (currentPage: number, totalPages: number) => void) => void;
|
|
|
|
// Internal - for bridges to trigger immediate updates
|
|
triggerImmediateScrollUpdate: (currentPage: number, totalPages: number) => void;
|
|
triggerImmediateZoomUpdate: (zoomPercent: number) => void;
|
|
|
|
// Action handlers - call EmbedPDF APIs directly
|
|
scrollActions: {
|
|
scrollToPage: (page: number) => void;
|
|
scrollToFirstPage: () => void;
|
|
scrollToPreviousPage: () => void;
|
|
scrollToNextPage: () => void;
|
|
scrollToLastPage: () => void;
|
|
};
|
|
|
|
zoomActions: {
|
|
zoomIn: () => void;
|
|
zoomOut: () => void;
|
|
toggleMarqueeZoom: () => void;
|
|
requestZoom: (level: number) => void;
|
|
};
|
|
|
|
panActions: {
|
|
enablePan: () => void;
|
|
disablePan: () => void;
|
|
togglePan: () => void;
|
|
};
|
|
|
|
selectionActions: {
|
|
copyToClipboard: () => void;
|
|
getSelectedText: () => string;
|
|
getFormattedSelection: () => unknown;
|
|
};
|
|
|
|
spreadActions: {
|
|
setSpreadMode: (mode: SpreadMode) => void;
|
|
getSpreadMode: () => SpreadMode | null;
|
|
toggleSpreadMode: () => void;
|
|
};
|
|
|
|
rotationActions: {
|
|
rotateForward: () => void;
|
|
rotateBackward: () => void;
|
|
setRotation: (rotation: number) => void;
|
|
getRotation: () => number;
|
|
};
|
|
|
|
searchActions: {
|
|
search: (query: string) => Promise<void>;
|
|
next: () => void;
|
|
previous: () => void;
|
|
clear: () => void;
|
|
};
|
|
|
|
exportActions: {
|
|
download: () => void;
|
|
saveAsCopy: () => Promise<ArrayBuffer | null>;
|
|
};
|
|
|
|
// Bridge registration - internal use by bridges
|
|
registerBridge: (type: string, ref: BridgeRef) => void;
|
|
}
|
|
|
|
export const ViewerContext = createContext<ViewerContextType | null>(null);
|
|
|
|
interface ViewerProviderProps {
|
|
children: ReactNode;
|
|
}
|
|
|
|
export const ViewerProvider: React.FC<ViewerProviderProps> = ({ children }) => {
|
|
// UI state - only state directly managed by this context
|
|
const [isThumbnailSidebarVisible, setIsThumbnailSidebarVisible] = useState(false);
|
|
const [isAnnotationsVisible, setIsAnnotationsVisible] = useState(true);
|
|
const [isAnnotationMode, setIsAnnotationModeState] = useState(false);
|
|
const [activeFileIndex, setActiveFileIndex] = useState(0);
|
|
|
|
// Get current navigation state to check if we're in sign mode
|
|
useNavigation();
|
|
|
|
// Bridge registry - bridges register their state and APIs here
|
|
const bridgeRefs = useRef({
|
|
scroll: null as BridgeRef<ScrollState, ScrollAPIWrapper> | null,
|
|
zoom: null as BridgeRef<ZoomState, ZoomAPIWrapper> | null,
|
|
pan: null as BridgeRef<PanState, PanAPIWrapper> | null,
|
|
selection: null as BridgeRef<SelectionState, SelectionAPIWrapper> | null,
|
|
search: null as BridgeRef<SearchState, SearchAPIWrapper> | null,
|
|
spread: null as BridgeRef<SpreadState, SpreadAPIWrapper> | null,
|
|
rotation: null as BridgeRef<RotationState, RotationAPIWrapper> | null,
|
|
thumbnail: null as BridgeRef<unknown, ThumbnailAPIWrapper> | null,
|
|
export: null as BridgeRef<ExportState, ExportAPIWrapper> | null,
|
|
});
|
|
|
|
// Immediate zoom callback for responsive display updates
|
|
const immediateZoomUpdateCallback = useRef<((percent: number) => void) | null>(null);
|
|
|
|
// Immediate scroll callback for responsive display updates
|
|
const immediateScrollUpdateCallback = useRef<((currentPage: number, totalPages: number) => void) | null>(null);
|
|
|
|
const registerBridge = (type: string, ref: BridgeRef) => {
|
|
// Type-safe assignment - we know the bridges will provide correct types
|
|
switch (type) {
|
|
case 'scroll':
|
|
bridgeRefs.current.scroll = ref as BridgeRef<ScrollState, ScrollAPIWrapper>;
|
|
break;
|
|
case 'zoom':
|
|
bridgeRefs.current.zoom = ref as BridgeRef<ZoomState, ZoomAPIWrapper>;
|
|
break;
|
|
case 'pan':
|
|
bridgeRefs.current.pan = ref as BridgeRef<PanState, PanAPIWrapper>;
|
|
break;
|
|
case 'selection':
|
|
bridgeRefs.current.selection = ref as BridgeRef<SelectionState, SelectionAPIWrapper>;
|
|
break;
|
|
case 'search':
|
|
bridgeRefs.current.search = ref as BridgeRef<SearchState, SearchAPIWrapper>;
|
|
break;
|
|
case 'spread':
|
|
bridgeRefs.current.spread = ref as BridgeRef<SpreadState, SpreadAPIWrapper>;
|
|
break;
|
|
case 'rotation':
|
|
bridgeRefs.current.rotation = ref as BridgeRef<RotationState, RotationAPIWrapper>;
|
|
break;
|
|
case 'thumbnail':
|
|
bridgeRefs.current.thumbnail = ref as BridgeRef<unknown, ThumbnailAPIWrapper>;
|
|
break;
|
|
case 'export':
|
|
bridgeRefs.current.export = ref as BridgeRef<ExportState, ExportAPIWrapper>;
|
|
break;
|
|
}
|
|
};
|
|
|
|
const toggleThumbnailSidebar = useCallback(() => {
|
|
setIsThumbnailSidebarVisible(prev => !prev);
|
|
}, []);
|
|
|
|
const toggleAnnotationsVisibility = useCallback(() => {
|
|
setIsAnnotationsVisible(prev => !prev);
|
|
}, []);
|
|
|
|
const setAnnotationMode = useCallback((enabled: boolean) => {
|
|
setIsAnnotationModeState(enabled);
|
|
}, []);
|
|
|
|
const toggleAnnotationMode = useCallback(() => {
|
|
setIsAnnotationModeState(prev => !prev);
|
|
}, []);
|
|
|
|
// State getters - read from bridge refs
|
|
const getScrollState = (): ScrollState => {
|
|
return bridgeRefs.current.scroll?.state || { currentPage: 1, totalPages: 0 };
|
|
};
|
|
|
|
const getZoomState = (): ZoomState => {
|
|
return bridgeRefs.current.zoom?.state || { currentZoom: 1.4, zoomPercent: 140 };
|
|
};
|
|
|
|
const getPanState = (): PanState => {
|
|
return bridgeRefs.current.pan?.state || { isPanning: false };
|
|
};
|
|
|
|
const getSelectionState = (): SelectionState => {
|
|
return bridgeRefs.current.selection?.state || { hasSelection: false };
|
|
};
|
|
|
|
const getSpreadState = (): SpreadState => {
|
|
return bridgeRefs.current.spread?.state || { spreadMode: SpreadMode.None, isDualPage: false };
|
|
};
|
|
|
|
const getRotationState = (): RotationState => {
|
|
return bridgeRefs.current.rotation?.state || { rotation: 0 };
|
|
};
|
|
|
|
const getSearchState = (): SearchState => {
|
|
return bridgeRefs.current.search?.state || { results: null, activeIndex: 0 };
|
|
};
|
|
|
|
const getThumbnailAPI = () => {
|
|
return bridgeRefs.current.thumbnail?.api || null;
|
|
};
|
|
|
|
const getExportState = (): ExportState => {
|
|
return bridgeRefs.current.export?.state || { canExport: false };
|
|
};
|
|
|
|
// Action handlers - call APIs directly
|
|
const scrollActions = useMemo(() => ({
|
|
scrollToPage: (page: number) => {
|
|
const api = bridgeRefs.current.scroll?.api;
|
|
if (api?.scrollToPage) {
|
|
api.scrollToPage({ pageNumber: page });
|
|
}
|
|
},
|
|
scrollToFirstPage: () => {
|
|
const api = bridgeRefs.current.scroll?.api;
|
|
if (api?.scrollToPage) {
|
|
api.scrollToPage({ pageNumber: 1 });
|
|
}
|
|
},
|
|
scrollToPreviousPage: () => {
|
|
const api = bridgeRefs.current.scroll?.api;
|
|
if (api?.scrollToPreviousPage) {
|
|
api.scrollToPreviousPage();
|
|
}
|
|
},
|
|
scrollToNextPage: () => {
|
|
const api = bridgeRefs.current.scroll?.api;
|
|
if (api?.scrollToNextPage) {
|
|
api.scrollToNextPage();
|
|
}
|
|
},
|
|
scrollToLastPage: () => {
|
|
const scrollState = getScrollState();
|
|
const api = bridgeRefs.current.scroll?.api;
|
|
if (api?.scrollToPage && scrollState.totalPages > 0) {
|
|
api.scrollToPage({ pageNumber: scrollState.totalPages });
|
|
}
|
|
}
|
|
}), []);
|
|
|
|
const zoomActions = useMemo(() => ({
|
|
zoomIn: () => {
|
|
const api = bridgeRefs.current.zoom?.api;
|
|
if (api?.zoomIn) {
|
|
// Update display immediately if callback is registered
|
|
if (immediateZoomUpdateCallback.current) {
|
|
const currentState = getZoomState();
|
|
const newPercent = Math.min(Math.round(currentState.zoomPercent * 1.2), 300);
|
|
immediateZoomUpdateCallback.current(newPercent);
|
|
}
|
|
api.zoomIn();
|
|
}
|
|
},
|
|
zoomOut: () => {
|
|
const api = bridgeRefs.current.zoom?.api;
|
|
if (api?.zoomOut) {
|
|
// Update display immediately if callback is registered
|
|
if (immediateZoomUpdateCallback.current) {
|
|
const currentState = getZoomState();
|
|
const newPercent = Math.max(Math.round(currentState.zoomPercent / 1.2), 20);
|
|
immediateZoomUpdateCallback.current(newPercent);
|
|
}
|
|
api.zoomOut();
|
|
}
|
|
},
|
|
toggleMarqueeZoom: () => {
|
|
const api = bridgeRefs.current.zoom?.api;
|
|
if (api?.toggleMarqueeZoom) {
|
|
api.toggleMarqueeZoom();
|
|
}
|
|
},
|
|
requestZoom: (level: number) => {
|
|
const api = bridgeRefs.current.zoom?.api;
|
|
if (api?.requestZoom) {
|
|
api.requestZoom(level);
|
|
}
|
|
}
|
|
}), []);
|
|
|
|
const panActions = useMemo(() => ({
|
|
enablePan: () => {
|
|
const api = bridgeRefs.current.pan?.api;
|
|
if (api?.enable) {
|
|
api.enable();
|
|
}
|
|
},
|
|
disablePan: () => {
|
|
const api = bridgeRefs.current.pan?.api;
|
|
if (api?.disable) {
|
|
api.disable();
|
|
}
|
|
},
|
|
togglePan: () => {
|
|
const api = bridgeRefs.current.pan?.api;
|
|
if (api?.toggle) {
|
|
api.toggle();
|
|
}
|
|
}
|
|
}), []);
|
|
|
|
const selectionActions = useMemo(() => ({
|
|
copyToClipboard: () => {
|
|
const api = bridgeRefs.current.selection?.api;
|
|
if (api?.copyToClipboard) {
|
|
api.copyToClipboard();
|
|
}
|
|
},
|
|
getSelectedText: () => {
|
|
const api = bridgeRefs.current.selection?.api;
|
|
if (api?.getSelectedText) {
|
|
return api.getSelectedText();
|
|
}
|
|
return '';
|
|
},
|
|
getFormattedSelection: () => {
|
|
const api = bridgeRefs.current.selection?.api;
|
|
if (api?.getFormattedSelection) {
|
|
return api.getFormattedSelection();
|
|
}
|
|
return null;
|
|
}
|
|
}), []);
|
|
|
|
const spreadActions = useMemo(() => ({
|
|
setSpreadMode: (mode: SpreadMode) => {
|
|
const api = bridgeRefs.current.spread?.api;
|
|
if (api?.setSpreadMode) {
|
|
api.setSpreadMode(mode);
|
|
}
|
|
},
|
|
getSpreadMode: () => {
|
|
const api = bridgeRefs.current.spread?.api;
|
|
if (api?.getSpreadMode) {
|
|
return api.getSpreadMode();
|
|
}
|
|
return null;
|
|
},
|
|
toggleSpreadMode: () => {
|
|
const api = bridgeRefs.current.spread?.api;
|
|
if (api?.toggleSpreadMode) {
|
|
api.toggleSpreadMode();
|
|
}
|
|
}
|
|
}), []);
|
|
|
|
const rotationActions = useMemo(() => ({
|
|
rotateForward: () => {
|
|
const api = bridgeRefs.current.rotation?.api;
|
|
if (api?.rotateForward) {
|
|
api.rotateForward();
|
|
}
|
|
},
|
|
rotateBackward: () => {
|
|
const api = bridgeRefs.current.rotation?.api;
|
|
if (api?.rotateBackward) {
|
|
api.rotateBackward();
|
|
}
|
|
},
|
|
setRotation: (rotation: number) => {
|
|
const api = bridgeRefs.current.rotation?.api;
|
|
if (api?.setRotation) {
|
|
api.setRotation(rotation);
|
|
}
|
|
},
|
|
getRotation: () => {
|
|
const api = bridgeRefs.current.rotation?.api;
|
|
if (api?.getRotation) {
|
|
return api.getRotation();
|
|
}
|
|
return 0;
|
|
}
|
|
}), []);
|
|
|
|
const searchActions = useMemo(() => ({
|
|
search: async (query: string) => {
|
|
const api = bridgeRefs.current.search?.api;
|
|
if (api?.search) {
|
|
return api.search(query);
|
|
}
|
|
},
|
|
next: () => {
|
|
const api = bridgeRefs.current.search?.api;
|
|
if (api?.next) {
|
|
api.next();
|
|
}
|
|
},
|
|
previous: () => {
|
|
const api = bridgeRefs.current.search?.api;
|
|
if (api?.previous) {
|
|
api.previous();
|
|
}
|
|
},
|
|
clear: () => {
|
|
const api = bridgeRefs.current.search?.api;
|
|
if (api?.clear) {
|
|
api.clear();
|
|
}
|
|
}
|
|
}), []);
|
|
|
|
const exportActions = useMemo(() => ({
|
|
download: () => {
|
|
const api = bridgeRefs.current.export?.api;
|
|
if (api?.download) {
|
|
api.download();
|
|
}
|
|
},
|
|
saveAsCopy: async () => {
|
|
const api = bridgeRefs.current.export?.api;
|
|
if (api?.saveAsCopy) {
|
|
try {
|
|
const result = api.saveAsCopy();
|
|
return await result.toPromise();
|
|
} catch (error) {
|
|
console.error('Failed to save PDF copy:', error);
|
|
return null;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}), []);
|
|
|
|
const registerImmediateZoomUpdate = useCallback((callback: (percent: number) => void) => {
|
|
immediateZoomUpdateCallback.current = callback;
|
|
}, []);
|
|
|
|
const registerImmediateScrollUpdate = useCallback((callback: (currentPage: number, totalPages: number) => void) => {
|
|
immediateScrollUpdateCallback.current = callback;
|
|
}, []);
|
|
|
|
const triggerImmediateScrollUpdate = useCallback((currentPage: number, totalPages: number) => {
|
|
if (immediateScrollUpdateCallback.current) {
|
|
immediateScrollUpdateCallback.current(currentPage, totalPages);
|
|
}
|
|
}, []);
|
|
|
|
const triggerImmediateZoomUpdate = useCallback((zoomPercent: number) => {
|
|
if (immediateZoomUpdateCallback.current) {
|
|
immediateZoomUpdateCallback.current(zoomPercent);
|
|
}
|
|
}, []);
|
|
|
|
const value = useMemo<ViewerContextType>(() => ({
|
|
// UI state
|
|
isThumbnailSidebarVisible,
|
|
toggleThumbnailSidebar,
|
|
|
|
// Annotation controls
|
|
isAnnotationsVisible,
|
|
toggleAnnotationsVisibility,
|
|
isAnnotationMode,
|
|
setAnnotationMode,
|
|
toggleAnnotationMode,
|
|
|
|
// Active file index
|
|
activeFileIndex,
|
|
setActiveFileIndex,
|
|
|
|
// State getters
|
|
getScrollState,
|
|
getZoomState,
|
|
getPanState,
|
|
getSelectionState,
|
|
getSpreadState,
|
|
getRotationState,
|
|
getSearchState,
|
|
getThumbnailAPI,
|
|
getExportState,
|
|
|
|
// Immediate updates
|
|
registerImmediateZoomUpdate,
|
|
registerImmediateScrollUpdate,
|
|
triggerImmediateScrollUpdate,
|
|
triggerImmediateZoomUpdate,
|
|
|
|
// Actions
|
|
scrollActions,
|
|
zoomActions,
|
|
panActions,
|
|
selectionActions,
|
|
spreadActions,
|
|
rotationActions,
|
|
searchActions,
|
|
exportActions,
|
|
|
|
// Bridge registration
|
|
registerBridge,
|
|
}), [
|
|
isThumbnailSidebarVisible,
|
|
isAnnotationsVisible,
|
|
isAnnotationMode,
|
|
activeFileIndex,
|
|
scrollActions,
|
|
zoomActions,
|
|
panActions,
|
|
selectionActions,
|
|
spreadActions,
|
|
rotationActions,
|
|
searchActions,
|
|
exportActions,
|
|
]);
|
|
|
|
return (
|
|
<ViewerContext.Provider value={value}>
|
|
{children}
|
|
</ViewerContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useViewer = (): ViewerContextType => {
|
|
const context = useContext(ViewerContext);
|
|
if (!context) {
|
|
throw new Error('useViewer must be used within a ViewerProvider');
|
|
}
|
|
return context;
|
|
};
|