Files
Stirling-PDF/frontend/src/core/contexts/ViewerContext.tsx
T
Reece 7de8347472 Squashed commit of the following:
commit f1901a2e56
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 27 18:23:27 2025 +0000

    revert lint

commit 09b0fbefcd
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 27 15:47:38 2025 +0000

    Hide file names in posthog

commit 3497ccd7bd
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 27 12:45:31 2025 +0000

    remove page break settings modal

commit 5e27dc88f8
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 27 12:37:00 2025 +0000

    retain interleaving

commit b276eb5b68
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 27 11:32:31 2025 +0000

    Lint

commit aec1f97ff8
Author: Reece <reece@stirlingpdf.com>
Date:   Sat Oct 25 14:19:32 2025 +0100

    -

commit fbe2dc2958
Author: Reece <reece@stirlingpdf.com>
Date:   Sat Oct 25 13:06:10 2025 +0100

    Fixed file reordering placeholder

commit aaae81c68e
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 24 15:57:30 2025 +0100

    -

commit 3aa77819f2
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 24 15:54:30 2025 +0100

    -

commit 28dab07870
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 24 15:51:37 2025 +0100

    -

commit ed6199de61
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 24 15:51:29 2025 +0100

    lint and revert onboarding

commit 4d59ebfb2a
Author: 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

commit ea4f37cccf
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 24 15:06:21 2025 +0100

    Merge history change

commit c25131ae9b
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 24 14:48:14 2025 +0100

     lint

commit 25df9410cd
Merge: 494f92421 848ff9688
Author: 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

commit 494f92421f
Author: 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.

commit eef5dce849
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 24 11:33:31 2025 +0100

    Drag and drop improvements basic box select

commit ddefe81082
Author: 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

commit be037b727f
Author: Reece <reece@stirlingpdf.com>
Date:   Thu Oct 23 18:15:37 2025 +0100

    File reorder logic

commit 7a56f0504e
Author: 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

commit f7c9855489
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 21:45:00 2025 +0100

    glow scaling

commit 36a358f907
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 21:25:44 2025 +0100

    Visual tweaks

commit 0bcb1810d6
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 21:08:18 2025 +0100

    tweak

commit aee535214d
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 20:55:45 2025 +0100

    Pretty lights

commit 6d3154a7ae
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 20:44:48 2025 +0100

    Update top bar controls visually

commit 658ce2dab9
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 18:45:14 2025 +0100

    add file

commit 15df5cf168
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 18:05:55 2025 +0100

    -

commit 23d7f38100
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 17:24:16 2025 +0100

    lint

commit 472fc2939e
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 15:56:54 2025 +0100

    lint 2

commit a21047e8b0
Merge: 8ee03fa1c 3e23dc59b
Author: 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

commit 8ee03fa1c6
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 15:50:14 2025 +0100

    Lint

commit a22913e1e4
Author: Reece <reece@stirlingpdf.com>
Date:   Mon Oct 20 14:16:41 2025 +0100

    page editor fixes post merge

commit b3c0c69a7c
Merge: 2289080f9 3e6236d95
Author: 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

commit 2289080f9c
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 17 16:55:29 2025 +0100

    remove buttons

commit a5ec62fa08
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 17 15:24:05 2025 +0100

    Performance improvements

commit e7f7b7e201
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 17 14:15:21 2025 +0100

    improved

commit 74e8388bce
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 15 21:33:54 2025 +0100

    Working mostly

commit e7c6db082c
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 15 16:31:30 2025 +0100

    Rejig arrays

commit 05a7161412
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 15 00:01:30 2025 +0100

    Structural tweaks

commit 39267e795c
Author: Reece <reece@stirlingpdf.com>
Date:   Tue Oct 14 12:41:50 2025 +0100

    Reworked page editor - dirty commit

commit 6acce968a5
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 19:32:41 2025 +0100

    fix 2

commit 0722ecc6c4
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 19:27:15 2025 +0100

    fix

commit 3597a8b7bd
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 19:16:04 2025 +0100

    Initial set up

commit c260394b95
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 17:15:07 2025 +0100

    Cleanup

commit 93fcfb280a
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 17:09:36 2025 +0100

    Remove logs tweak visuals, use fit text component

commit 69cb8e7aec
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 16:54:05 2025 +0100

    Fix signwith tab based system

commit 8e8e06628e
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 15:57:41 2025 +0100

    Nav based file select

commit 5d3710260f
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 13:37:52 2025 +0100

    Lint

commit ad8789d82a
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 13:35:18 2025 +0100

    remove file that came from nowhere

commit 749966a197
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 13:30:15 2025 +0100

    Remove mantine theme

commit d9e429aa3a
Merge: ad0b6cf2d b695e3900
Author: 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

commit ad0b6cf2d6
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Oct 10 12:55:03 2025 +0100

    Viewer tabs, embed update and layout fixes

commit b63f2c16a2
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 8 15:12:39 2025 +0100

    Remove unused legacy text signing Linting errors

commit edcc788d1a
Merge: 5b47ab5bb fdba336c0
Author: 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

commit 5b47ab5bbf
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 8 15:02:33 2025 +0100

    Remove debug logs

commit fdba336c05
Author: 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>

commit 5db6b85fb9
Merge: 70d941a40 13e88943b
Author: 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

commit 70d941a400
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 8 14:55:43 2025 +0100

    translations

commit 13e88943b7
Author: 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>

commit 339e5cfb65
Author: 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>

commit 10944d9d57
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 8 14:45:39 2025 +0100

    Remove debug logging

commit 0c9f460fb6
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 8 14:02:43 2025 +0100

    Remove arbitrary timers

commit fa6e01b46e
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Oct 8 12:26:34 2025 +0100

    Clean up

commit 23f85d7267
Author: Reece <reece@stirlingpdf.com>
Date:   Tue Oct 7 22:40:58 2025 +0100

    tweaks

commit f6290c0238
Author: Reece <reece@stirlingpdf.com>
Date:   Tue Oct 7 21:52:40 2025 +0100

    - Refactored signature saving process

commit 991be9ffa2
Author: 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

commit 07bf79f3ee
Author: Reece <reece@stirlingpdf.com>
Date:   Tue Oct 7 14:54:14 2025 +0100

    Improved canvas mode with signaturepad.js

commit 3a0acd0a21
Author: Reece <reece@stirlingpdf.com>
Date:   Tue Oct 7 12:56:12 2025 +0100

    Single canvas

commit fff637286f
Author: 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>

commit 8f94c8f57e
Merge: 708a296f8 2a29bda34
Author: 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

commit 708a296f8d
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 19:14:40 2025 +0100

    Auto update canvas signature

commit b486d1270e
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 19:03:24 2025 +0100

    Fix flicker on apply

commit 80faf0bc1e
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 18:55:09 2025 +0100

    -

commit 6555a9554a
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 18:53:16 2025 +0100

    Fix even more linting errors (Thanks James)

commit fdee719c89
Merge: 1be48c276 fd9fb9b97
Author: 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

commit 1be48c276b
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 18:12:13 2025 +0100

    fix text infinite loop

commit 2b6b7a8e1d
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 18:04:01 2025 +0100

    better error handling and killing logs

commit fd9fb9b972
Author: 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>

commit d8d6197008
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 17:48:41 2025 +0100

    fix page count issue

commit 1edd133e09
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 17:31:44 2025 +0100

    license checker use commonJS

commit 8685bf2a7c
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 17:26:19 2025 +0100

    gap

commit 36475069de
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 17:23:16 2025 +0100

    lint fix

commit 3aa8572c9e
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 17:16:17 2025 +0100

    Fix suggestions

commit 2e2d8477b9
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 17:01:06 2025 +0100

    Clean up

commit 90880eddf9
Author: 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>

commit 31fd6886dc
Merge: 3fdbf425b abc0988fd
Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
Date:   Fri Sep 26 16:40:34 2025 +0100

    Merge branch 'V2' into feature/v2/sign

commit 3fdbf425b4
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 16:39:38 2025 +0100

    Fix lintineg errors

commit 50e60d4972
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 16:27:52 2025 +0100

    Simple export block

commit a22330ebf4
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 16:09:20 2025 +0100

    Only flatten current annotations

commit 172f622c5f
Merge: cfd00b2c7 d82b958d9
Author: 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

commit cfd00b2c71
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 15:10:47 2025 +0100

    Render signature to pdf

commit d82b958d9f
Merge: c94ee388f 0bdc6466c
Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
Date:   Fri Sep 26 12:53:54 2025 +0100

    Merge branch 'V2' into feature/v2/sign

commit c94ee388fc
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 12:47:32 2025 +0100

    Restructure and bug fix

commit aa5333dcd9
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 03:23:59 2025 +0100

    Change to button based placement to avoid performance issue on canvas

commit a8265efff4
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 03:19:05 2025 +0100

    Improved performance

commit b9b425aba0
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 02:18:47 2025 +0100

    Fix undo/redo

commit 51caad636c
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 01:51:17 2025 +0100

    Reduce logs

commit 023fd43b72
Author: Reece <reece@stirlingpdf.com>
Date:   Fri Sep 26 01:49:33 2025 +0100

    Save file

commit a8a0808274
Author: Reece <reece@stirlingpdf.com>
Date:   Thu Sep 25 09:46:20 2025 +0100

    history tweaks

commit 3d2607f72a
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Sep 24 19:01:36 2025 +0100

    fixes

commit f9542a9257
Merge: a12e45757 963787316
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Sep 24 18:35:16 2025 +0100

    Merge branch 'feature/v2/exportpdf' into feature/v2/sign

commit 963787316a
Author: Reece <reece@stirlingpdf.com>
Date:   Wed Sep 24 17:42:58 2025 +0100

    Export with embedpdf

commit a12e457577
Author: 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.

commit bac61c7e9e
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Tue Sep 23 18:16:21 2025 +0100

    Delete signature

commit fc2f34ee15
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Tue Sep 23 17:18:39 2025 +0100

    fix add image

commit d9798badae
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Tue Sep 23 14:06:41 2025 +0100

    Fix sidebar refresh. Updated UI

commit efc0c1aab3
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Tue Sep 23 12:24:58 2025 +0100

    text and improved drawing

commit 10672403c9
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 22 14:14:35 2025 +0100

    Colours on document draw + translations

commit 32fed96aa7
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 22 14:03:49 2025 +0100

    Canvas and dosument draw split, drawing improvements

commit a70472b172
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Sat Sep 20 01:59:04 2025 +0100

    Initial set up

commit 3b87ca0c3c
Merge: 0e1da982b 6172351ee
Author: 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

commit 0e1da982b6
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 19 11:38:53 2025 +0100

    Fix vite

commit 6172351eed
Merge: 1174b6a4d ae7be50ec
Author: 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

commit 1174b6a4da
Merge: a970c44d0 21a2433dd
Author: 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

commit a970c44d03
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 19 11:14:58 2025 +0100

    improvements

commit b574cef54a
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 19 10:48:29 2025 +0100

    improvements

commit 21a2433dd8
Author: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
Date:   Thu Sep 18 13:14:44 2025 +0100

    Remove marginTop style from Workbench component

commit 07cc250176
Author: 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.

commit dc71b3007b
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 18 12:32:42 2025 +0100

    clean up

commit 1598057ed0
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 18 08:44:57 2025 +0100

    Tweaks

commit 312fc2d615
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 18 02:14:31 2025 +0100

    Clean up

commit 72375d89d1
Merge: a990ecc02 7ff1c66d0
Author: 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

commit a990ecc02a
Merge: da6ecc661 b51c2e42a
Author: 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

commit da6ecc6619
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Wed Sep 17 14:35:44 2025 +0100

    Fix scroll page identification

commit dac176f0c6
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Wed Sep 17 12:07:44 2025 +0100

    Fix colours

commit 41e5a7fbd6
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Wed Sep 17 12:00:20 2025 +0100

    Restructure to avoid global variables
    fix zoom

commit b81ed9ec2e
Merge: 9b5c50db0 81c5d8ff4
Author: 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

commit 9b5c50db07
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Tue Sep 16 19:36:36 2025 +0100

    Improved Structure with context at root

commit 81c5d8ff46
Author: James Brunton <james@stirlingpdf.com>
Date:   Tue Sep 16 16:06:40 2025 +0100

    Potential fix for mime type issues

commit a67f5199d3
Author: James Brunton <james@stirlingpdf.com>
Date:   Tue Sep 16 16:06:27 2025 +0100

    Improvements for scroll gestures

commit 3755bfde34
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 15 18:20:11 2025 +0100

    Set zoom to 140%

commit 2834eec3be
Merge: 19d7111ca d89e1b5b1
Author: 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

commit d89e1b5b1e
Merge: 5d7fb638a a57373b96
Author: 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

commit 19d7111cab
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 15 17:27:22 2025 +0100

    Remove unused code

commit ca9d7ef465
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 15 17:03:52 2025 +0100

    Remove unused code

commit fad4f84c9c
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 15 16:53:41 2025 +0100

    translations

commit 35863ac610
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 15 16:53:32 2025 +0100

    remove select mode

commit c17dd25069
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 15 16:05:19 2025 +0100

    Rotate

commit 5d7fb638af
Merge: 2fb4710dd 7dad484aa
Author: 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

commit 2fb4710dd7
Merge: 85a74c1d4 cfdb6eaa1
Author: 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

commit 85a74c1d46
Merge: 21a93d6ca 9599bca8a
Author: 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

commit 21a93d6cac
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Mon Sep 15 13:33:39 2025 +0100

    Context based right rail controls for viewer

commit 9599bca8a9
Author: 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>

commit 1709ca9049
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 12 16:38:29 2025 +0100

    Rems

commit 18e4e03220
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 12 16:26:05 2025 +0100

    rename APIBridge

commit 9901771572
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 12 16:19:07 2025 +0100

    improve search

commit 514956570c
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 12 15:06:06 2025 +0100

    pan state improvements

commit 423617db52
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 12 14:21:31 2025 +0100

    thumbnail sidebar

commit 143f0c5031
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 12 01:56:51 2025 +0100

    search pdf

commit 368e9801a1
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Fri Sep 12 00:35:27 2025 +0100

    Zoom with wheel and +/-

commit afc9ca5858
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 11 23:52:38 2025 +0100

    spread/multipage

commit 8815575124
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 11 22:51:10 2025 +0100

    pan

commit fb9b01f53b
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 11 20:07:43 2025 +0100

    improved scaling and fix grey void

commit 93607937f6
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 11 19:38:04 2025 +0100

    selection also

commit 687ab39286
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 11 19:36:44 2025 +0100

    Text selection

commit 83a3222cf6
Author: Reece Browne <reecebrowne1995@gmail.com>
Date:   Thu Sep 11 19:08:44 2025 +0100

    Set up
2025-10-28 14:39:11 +00:00

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;
};