@arbidocs/blocks 0.5.120 → 0.5.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ClippingMediaViewer-IEIBT74X.cjs +156 -0
- package/dist/ClippingMediaViewer-IEIBT74X.cjs.map +1 -0
- package/dist/ClippingPdfViewer-OGYLMVCE.cjs +79 -0
- package/dist/ClippingPdfViewer-OGYLMVCE.cjs.map +1 -0
- package/dist/{ConnectedCallDock-WER7R222.cjs → ConnectedCallDock-XJOYVVAH.cjs} +9 -7
- package/dist/ConnectedCallDock-XJOYVVAH.cjs.map +1 -0
- package/dist/{ConnectedCallRoom-T7OBQTYP.cjs → ConnectedCallRoom-CUDYAPQK.cjs} +9 -7
- package/dist/{ConnectedCallRoom-T7OBQTYP.cjs.map → ConnectedCallRoom-CUDYAPQK.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs → ConnectedNativeDocxComparison-QKHCYD6W.cjs} +7 -7
- package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs.map → ConnectedNativeDocxComparison-QKHCYD6W.cjs.map} +1 -1
- package/dist/ConnectedPresentation-AU25OW25.cjs +321 -0
- package/dist/ConnectedPresentation-AU25OW25.cjs.map +1 -0
- package/dist/ConnectedSlidesTab-I75LKKN7.cjs +236 -0
- package/dist/ConnectedSlidesTab-I75LKKN7.cjs.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs → ConnectedStreamedWordArtifact-AG62232A.cjs} +7 -7
- package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs.map → ConnectedStreamedWordArtifact-AG62232A.cjs.map} +1 -1
- package/dist/{DocumentReviewCard-BPIAJJED.cjs → DocumentReviewCard-M53XFLI2.cjs} +15 -14
- package/dist/DocumentReviewCard-M53XFLI2.cjs.map +1 -0
- package/dist/{FilesViewerDialog-67WK3TZC.cjs → FilesViewerDialog-4352KIOG.cjs} +30 -22
- package/dist/FilesViewerDialog-4352KIOG.cjs.map +1 -0
- package/dist/{GridViewImpl-ZMJJWTOM.cjs → GridViewImpl-LTYET77Q.cjs} +3 -3
- package/dist/GridViewImpl-LTYET77Q.cjs.map +1 -0
- package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-3XYAV4BV.cjs} +9 -8
- package/dist/WorkspaceTableView-3XYAV4BV.cjs.map +1 -0
- package/dist/agents/index.cjs +186 -186
- package/dist/{ai-IM4A23YT.cjs → ai-IEIR7SC2.cjs} +17 -15
- package/dist/ai-IEIR7SC2.cjs.map +1 -0
- package/dist/calls/connected/CallControls.d.ts +2 -0
- package/dist/calls/connected/CallControls.js +71 -9
- package/dist/calls/connected/CallControls.js.map +2 -2
- package/dist/calls/connected/ShareDocumentDialog.d.ts +14 -0
- package/dist/calls/connected/ShareDocumentDialog.js +77 -0
- package/dist/calls/connected/ShareDocumentDialog.js.map +7 -0
- package/dist/calls/index.cjs +2 -2
- package/dist/chat/index.cjs +8 -7
- package/dist/{chunk-557MJ4IH.cjs → chunk-2F57IO7S.cjs} +9 -146
- package/dist/chunk-2F57IO7S.cjs.map +1 -0
- package/dist/chunk-2RLA6QO2.cjs +174 -0
- package/dist/chunk-2RLA6QO2.cjs.map +1 -0
- package/dist/chunk-4TTX6ZNS.cjs +1374 -0
- package/dist/chunk-4TTX6ZNS.cjs.map +1 -0
- package/dist/chunk-5GCCUXMT.cjs +63 -0
- package/dist/chunk-5GCCUXMT.cjs.map +1 -0
- package/dist/{chunk-BUVIBHFU.cjs → chunk-5QERK4PK.cjs} +38 -38
- package/dist/chunk-5QERK4PK.cjs.map +1 -0
- package/dist/chunk-6OK7ESTL.cjs +134 -0
- package/dist/chunk-6OK7ESTL.cjs.map +1 -0
- package/dist/{chunk-ECLUFKYR.cjs → chunk-7557LDAN.cjs} +4 -4
- package/dist/{chunk-ECLUFKYR.cjs.map → chunk-7557LDAN.cjs.map} +1 -1
- package/dist/{chunk-KTQOGT2L.cjs → chunk-7L4X6QN2.cjs} +7 -7
- package/dist/{chunk-KTQOGT2L.cjs.map → chunk-7L4X6QN2.cjs.map} +1 -1
- package/dist/{chunk-BP3IJ34D.cjs → chunk-7NLO7ASW.cjs} +4 -4
- package/dist/{chunk-BP3IJ34D.cjs.map → chunk-7NLO7ASW.cjs.map} +1 -1
- package/dist/{chunk-3GWWOYGS.cjs → chunk-7PN3YENO.cjs} +4 -4
- package/dist/{chunk-3GWWOYGS.cjs.map → chunk-7PN3YENO.cjs.map} +1 -1
- package/dist/{chunk-DFBDQKGE.cjs → chunk-ADDQKZ5I.cjs} +4 -4
- package/dist/{chunk-DFBDQKGE.cjs.map → chunk-ADDQKZ5I.cjs.map} +1 -1
- package/dist/chunk-AFQTQC7A.cjs +35 -0
- package/dist/chunk-AFQTQC7A.cjs.map +1 -0
- package/dist/{chunk-NLSWDP42.cjs → chunk-ALK3PUUB.cjs} +21 -11
- package/dist/chunk-ALK3PUUB.cjs.map +1 -0
- package/dist/{chunk-775S43W7.cjs → chunk-CQQQIZU4.cjs} +8 -8
- package/dist/{chunk-775S43W7.cjs.map → chunk-CQQQIZU4.cjs.map} +1 -1
- package/dist/{chunk-TDO5UWXF.cjs → chunk-E3L5DB5F.cjs} +5 -5
- package/dist/{chunk-TDO5UWXF.cjs.map → chunk-E3L5DB5F.cjs.map} +1 -1
- package/dist/chunk-GFUOCGY6.cjs +32 -0
- package/dist/chunk-GFUOCGY6.cjs.map +1 -0
- package/dist/chunk-HYUKPHCT.cjs +66 -0
- package/dist/chunk-HYUKPHCT.cjs.map +1 -0
- package/dist/{chunk-QQWHG3KF.cjs → chunk-JJZOL5MG.cjs} +4 -4
- package/dist/{chunk-QQWHG3KF.cjs.map → chunk-JJZOL5MG.cjs.map} +1 -1
- package/dist/chunk-K4763GD5.cjs +301 -0
- package/dist/chunk-K4763GD5.cjs.map +1 -0
- package/dist/{chunk-B3LZITVF.cjs → chunk-KA3F6TIH.cjs} +2 -442
- package/dist/chunk-KA3F6TIH.cjs.map +1 -0
- package/dist/{chunk-PGJYD67F.cjs → chunk-KNGZZC4O.cjs} +7 -6
- package/dist/chunk-KNGZZC4O.cjs.map +1 -0
- package/dist/{chunk-YYPZOEED.cjs → chunk-LHWOKOMP.cjs} +23 -2
- package/dist/chunk-LHWOKOMP.cjs.map +1 -0
- package/dist/{chunk-HA66DHW6.cjs → chunk-MLA2BJ2Y.cjs} +28 -28
- package/dist/chunk-MLA2BJ2Y.cjs.map +1 -0
- package/dist/{chunk-CPR6EHG7.cjs → chunk-NG2EE7HR.cjs} +134 -10
- package/dist/chunk-NG2EE7HR.cjs.map +1 -0
- package/dist/{chunk-CKCG4NDB.cjs → chunk-OHHKBURG.cjs} +29 -29
- package/dist/chunk-OHHKBURG.cjs.map +1 -0
- package/dist/{chunk-4XJEHKVZ.cjs → chunk-PIYYBPHH.cjs} +4 -4
- package/dist/{chunk-4XJEHKVZ.cjs.map → chunk-PIYYBPHH.cjs.map} +1 -1
- package/dist/{chunk-YYSBWMDJ.cjs → chunk-QG2U2JGX.cjs} +4 -4
- package/dist/{chunk-YYSBWMDJ.cjs.map → chunk-QG2U2JGX.cjs.map} +1 -1
- package/dist/{chunk-5IZFSAEZ.cjs → chunk-SDRYSLOX.cjs} +4 -4
- package/dist/{chunk-5IZFSAEZ.cjs.map → chunk-SDRYSLOX.cjs.map} +1 -1
- package/dist/{chunk-NJCK6V6U.cjs → chunk-T73BHNQX.cjs} +2 -58
- package/dist/chunk-T73BHNQX.cjs.map +1 -0
- package/dist/{chunk-EOG6OT5I.cjs → chunk-TXP2N3DC.cjs} +4 -4
- package/dist/{chunk-EOG6OT5I.cjs.map → chunk-TXP2N3DC.cjs.map} +1 -1
- package/dist/{chunk-6UTKM5AB.cjs → chunk-UFT22LAB.cjs} +75 -75
- package/dist/chunk-UFT22LAB.cjs.map +1 -0
- package/dist/chunk-USNTRL22.cjs +4790 -0
- package/dist/chunk-USNTRL22.cjs.map +1 -0
- package/dist/{chunk-X36UR4A7.cjs → chunk-UTJ223TI.cjs} +413 -90
- package/dist/chunk-UTJ223TI.cjs.map +1 -0
- package/dist/{chunk-VZCPMXWC.cjs → chunk-V6MW7B4B.cjs} +4 -4
- package/dist/{chunk-VZCPMXWC.cjs.map → chunk-V6MW7B4B.cjs.map} +1 -1
- package/dist/{chunk-T23UTIRI.cjs → chunk-VWBYE3XY.cjs} +5 -5
- package/dist/{chunk-T23UTIRI.cjs.map → chunk-VWBYE3XY.cjs.map} +1 -1
- package/dist/chunk-WFMWKPGY.cjs +102 -0
- package/dist/chunk-WFMWKPGY.cjs.map +1 -0
- package/dist/chunk-WOOOMTTA.cjs +19 -0
- package/dist/chunk-WOOOMTTA.cjs.map +1 -0
- package/dist/{chunk-W6INT5GS.cjs → chunk-WRLGLZIA.cjs} +8 -8
- package/dist/{chunk-W6INT5GS.cjs.map → chunk-WRLGLZIA.cjs.map} +1 -1
- package/dist/{chunk-CJYWHUZR.cjs → chunk-XCKHOXRP.cjs} +4 -4
- package/dist/{chunk-CJYWHUZR.cjs.map → chunk-XCKHOXRP.cjs.map} +1 -1
- package/dist/chunk-XF355M7O.cjs +154 -0
- package/dist/chunk-XF355M7O.cjs.map +1 -0
- package/dist/{chunk-Q6CLWOP2.cjs → chunk-XGM4VVNV.cjs} +34 -34
- package/dist/{chunk-Q6CLWOP2.cjs.map → chunk-XGM4VVNV.cjs.map} +1 -1
- package/dist/{chunk-6WMMZLEV.cjs → chunk-XJEXFEWG.cjs} +2 -27
- package/dist/chunk-XJEXFEWG.cjs.map +1 -0
- package/dist/chunk-XK4TVJKD.cjs +73 -0
- package/dist/chunk-XK4TVJKD.cjs.map +1 -0
- package/dist/{chunk-E7TE2WVT.cjs → chunk-ZVEW3JBT.cjs} +3 -3
- package/dist/{chunk-E7TE2WVT.cjs.map → chunk-ZVEW3JBT.cjs.map} +1 -1
- package/dist/collaboration/index.cjs +70 -70
- package/dist/components/ZoomSlider.d.ts +25 -0
- package/dist/components/ZoomSlider.js +59 -0
- package/dist/components/ZoomSlider.js.map +7 -0
- package/dist/connect/docx.cjs +10 -10
- package/dist/connect/index.cjs +1066 -1147
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/viewer.cjs +19 -12
- package/dist/connection/ai.d.ts +1 -1
- package/dist/connection/conversation/ConnectedMessage.js +1 -1
- package/dist/connection/conversation/ConnectedMessage.js.map +2 -2
- package/dist/connection/files/ConnectedNewFileMenu.d.ts +2 -1
- package/dist/connection/files/ConnectedNewFileMenu.js +9 -3
- package/dist/connection/files/ConnectedNewFileMenu.js.map +2 -2
- package/dist/connection/files/explorer/ConnectedFilesExplorer.js +1 -1
- package/dist/connection/files/explorer/ConnectedFilesExplorer.js.map +2 -2
- package/dist/connection/files/explorer/FileTiles.js +1 -1
- package/dist/connection/files/explorer/FileTiles.js.map +2 -2
- package/dist/connection/files/fields/documentField.js +1 -1
- package/dist/connection/files/fields/documentField.js.map +2 -2
- package/dist/connection/files/grid/documentColumns.js +1 -1
- package/dist/connection/files/grid/documentColumns.js.map +2 -2
- package/dist/connection/files/page/DocumentsFilterBarActions.js +17 -28
- package/dist/connection/files/page/DocumentsFilterBarActions.js.map +2 -2
- package/dist/connection/mail/useMailboxDefaults.js +1 -1
- package/dist/connection/mail/useMailboxDefaults.js.map +2 -2
- package/dist/connection/panels/useSessionPanelMode.js +3 -2
- package/dist/connection/panels/useSessionPanelMode.js.map +2 -2
- package/dist/connection/presentation/ClippingMediaViewer.d.ts +12 -0
- package/dist/connection/presentation/ClippingMediaViewer.js +153 -0
- package/dist/connection/presentation/ClippingMediaViewer.js.map +7 -0
- package/dist/connection/presentation/ClippingPdfViewer.d.ts +22 -0
- package/dist/connection/presentation/ClippingPdfViewer.js +75 -0
- package/dist/connection/presentation/ClippingPdfViewer.js.map +7 -0
- package/dist/connection/presentation/ConnectedPresentation.d.ts +12 -0
- package/dist/connection/presentation/ConnectedPresentation.js +100 -0
- package/dist/connection/presentation/ConnectedPresentation.js.map +7 -0
- package/dist/connection/presentation/ConnectedSlidesTab.d.ts +20 -0
- package/dist/connection/presentation/ConnectedSlidesTab.js +222 -0
- package/dist/connection/presentation/ConnectedSlidesTab.js.map +7 -0
- package/dist/connection/presentation/CropClipDialog.d.ts +11 -0
- package/dist/connection/presentation/CropClipDialog.js +86 -0
- package/dist/connection/presentation/CropClipDialog.js.map +7 -0
- package/dist/connection/presentation/GenerateTile.d.ts +4 -0
- package/dist/connection/presentation/GenerateTile.js +24 -0
- package/dist/connection/presentation/GenerateTile.js.map +7 -0
- package/dist/connection/presentation/LabelColumnMenu.d.ts +8 -0
- package/dist/connection/presentation/LabelColumnMenu.js +38 -0
- package/dist/connection/presentation/LabelColumnMenu.js.map +7 -0
- package/dist/connection/presentation/PresentationDialogs.d.ts +39 -0
- package/dist/connection/presentation/PresentationDialogs.js +295 -0
- package/dist/connection/presentation/PresentationDialogs.js.map +7 -0
- package/dist/connection/presentation/PresentationFileCard.d.ts +10 -0
- package/dist/connection/presentation/PresentationFileCard.js +35 -0
- package/dist/connection/presentation/PresentationFileCard.js.map +7 -0
- package/dist/connection/presentation/PresentationPill.d.ts +8 -0
- package/dist/connection/presentation/PresentationPill.js +39 -0
- package/dist/connection/presentation/PresentationPill.js.map +7 -0
- package/dist/connection/presentation/PresentationSlot.d.ts +7 -0
- package/dist/connection/presentation/PresentationSlot.js +35 -0
- package/dist/connection/presentation/PresentationSlot.js.map +7 -0
- package/dist/connection/presentation/requests.d.ts +21 -0
- package/dist/connection/presentation/requests.js +27 -0
- package/dist/connection/presentation/requests.js.map +7 -0
- package/dist/connection/presentation/useImageGeneration.d.ts +11 -0
- package/dist/connection/presentation/useImageGeneration.js +66 -0
- package/dist/connection/presentation/useImageGeneration.js.map +7 -0
- package/dist/connection/presentation/useLabelColumns.d.ts +15 -0
- package/dist/connection/presentation/useLabelColumns.js +33 -0
- package/dist/connection/presentation/useLabelColumns.js.map +7 -0
- package/dist/connection/presentation/usePresentationController.d.ts +15 -0
- package/dist/connection/presentation/usePresentationController.js +118 -0
- package/dist/connection/presentation/usePresentationController.js.map +7 -0
- package/dist/connection/presentation/usePresentationFiles.d.ts +44 -0
- package/dist/connection/presentation/usePresentationFiles.js +307 -0
- package/dist/connection/presentation/usePresentationFiles.js.map +7 -0
- package/dist/connection/presentation/useViewerClipping.d.ts +14 -0
- package/dist/connection/presentation/useViewerClipping.js +18 -0
- package/dist/connection/presentation/useViewerClipping.js.map +7 -0
- package/dist/connection/shell/ConnectedAppShell.js +5 -1
- package/dist/connection/shell/ConnectedAppShell.js.map +2 -2
- package/dist/connection/viewer/CleanViewControl.d.ts +8 -0
- package/dist/connection/viewer/CleanViewControl.js +76 -0
- package/dist/connection/viewer/CleanViewControl.js.map +7 -0
- package/dist/connection/viewer/ConnectedDocumentViewer.js +28 -29
- package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
- package/dist/connection/viewer/ViewerCropModal.d.ts +5 -0
- package/dist/connection/viewer/ViewerCropModal.js +22 -0
- package/dist/connection/viewer/ViewerCropModal.js.map +7 -0
- package/dist/connection/viewer/ViewerPdfPane.d.ts +3 -1
- package/dist/connection/viewer/ViewerPdfPane.js +41 -1
- package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
- package/dist/connection/viewer/documentPlace.d.ts +5 -4
- package/dist/connection/viewer/documentPlace.js +2 -2
- package/dist/connection/viewer/documentPlace.js.map +2 -2
- package/dist/connection/viewer/drafts.js +6 -4
- package/dist/connection/viewer/drafts.js.map +2 -2
- package/dist/connection/viewer/pdf/PdfClipOutlines.d.ts +11 -0
- package/dist/connection/viewer/pdf/PdfClipOutlines.js +42 -0
- package/dist/connection/viewer/pdf/PdfClipOutlines.js.map +7 -0
- package/dist/connection/viewer/pdf/clipOutlines.d.ts +17 -0
- package/dist/connection/viewer/pdf/clipOutlines.js +24 -0
- package/dist/connection/viewer/pdf/clipOutlines.js.map +7 -0
- package/dist/connection/viewer/pdf/passageHighlights.d.ts +2 -0
- package/dist/connection/viewer/pdf/passageHighlights.js +12 -1
- package/dist/connection/viewer/pdf/passageHighlights.js.map +2 -2
- package/dist/connection/viewer/pdf/usePdfClipOutlines.d.ts +7 -0
- package/dist/connection/viewer/pdf/usePdfClipOutlines.js +36 -0
- package/dist/connection/viewer/pdf/usePdfClipOutlines.js.map +7 -0
- package/dist/connection/viewer/pdf/usePdfPassageHighlights.js +11 -2
- package/dist/connection/viewer/pdf/usePdfPassageHighlights.js.map +2 -2
- package/dist/connection/viewer/shareDocument.d.ts +11 -0
- package/dist/connection/viewer/shareDocument.js +11 -0
- package/dist/connection/viewer/shareDocument.js.map +7 -0
- package/dist/connection/viewer/slidesTabChunk.d.ts +2 -0
- package/dist/connection/viewer/slidesTabChunk.js +9 -0
- package/dist/connection/viewer/slidesTabChunk.js.map +7 -0
- package/dist/connection/viewer/useCleanView.d.ts +14 -0
- package/dist/connection/viewer/useCleanView.js +29 -0
- package/dist/connection/viewer/useCleanView.js.map +7 -0
- package/dist/connection/viewer/useViewedDocument.d.ts +1 -0
- package/dist/connection/viewer/useViewedDocument.js +9 -1
- package/dist/connection/viewer/useViewedDocument.js.map +2 -2
- package/dist/connection/viewer/useViewerTabs.js +18 -4
- package/dist/connection/viewer/useViewerTabs.js.map +2 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.d.ts +14 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.js +5 -2
- package/dist/connection/workflows/ConnectedWorkflowStart.js.map +2 -2
- package/dist/databases/index.cjs +49 -49
- package/dist/document-tools/DocumentToolButtons.d.ts +2 -0
- package/dist/document-tools/DocumentToolButtons.js +22 -1
- package/dist/document-tools/DocumentToolButtons.js.map +2 -2
- package/dist/document-tools/index.cjs +16 -12
- package/dist/document-tools/index.d.ts +1 -1
- package/dist/document-tools/index.js +2 -0
- package/dist/document-tools/index.js.map +2 -2
- package/dist/embed/index.cjs +17 -15
- package/dist/files/GridViewImpl.js +1 -1
- package/dist/files/GridViewImpl.js.map +2 -2
- package/dist/files/ViewerChrome.d.ts +5 -1
- package/dist/files/ViewerChrome.js +16 -6
- package/dist/files/ViewerChrome.js.map +2 -2
- package/dist/files/index.cjs +224 -224
- package/dist/files/navigator/DocumentSearchList.js +1 -1
- package/dist/files/navigator/DocumentSearchList.js.map +2 -2
- package/dist/index.cjs +359 -356
- package/dist/index.cjs.map +1 -1
- package/dist/presentation/BoxActionBar.d.ts +11 -0
- package/dist/presentation/BoxActionBar.js +182 -0
- package/dist/presentation/BoxActionBar.js.map +7 -0
- package/dist/presentation/ClipActionBar.d.ts +26 -0
- package/dist/presentation/ClipActionBar.js +103 -0
- package/dist/presentation/ClipActionBar.js.map +7 -0
- package/dist/presentation/ClipCaptureOverlay.d.ts +14 -0
- package/dist/presentation/ClipCaptureOverlay.js +69 -0
- package/dist/presentation/ClipCaptureOverlay.js.map +7 -0
- package/dist/presentation/ClipImage.d.ts +21 -0
- package/dist/presentation/ClipImage.js +119 -0
- package/dist/presentation/ClipImage.js.map +7 -0
- package/dist/presentation/ClipTray.d.ts +11 -0
- package/dist/presentation/ClipTray.js +152 -0
- package/dist/presentation/ClipTray.js.map +7 -0
- package/dist/presentation/ClipViewControls.d.ts +11 -0
- package/dist/presentation/ClipViewControls.js +142 -0
- package/dist/presentation/ClipViewControls.js.map +7 -0
- package/dist/presentation/DesignMenu.d.ts +8 -0
- package/dist/presentation/DesignMenu.js +199 -0
- package/dist/presentation/DesignMenu.js.map +7 -0
- package/dist/presentation/LayoutMenu.d.ts +17 -0
- package/dist/presentation/LayoutMenu.js +122 -0
- package/dist/presentation/LayoutMenu.js.map +7 -0
- package/dist/presentation/MediaClip.d.ts +15 -0
- package/dist/presentation/MediaClip.js +67 -0
- package/dist/presentation/MediaClip.js.map +7 -0
- package/dist/presentation/Notice.d.ts +6 -0
- package/dist/presentation/Notice.js +43 -0
- package/dist/presentation/Notice.js.map +7 -0
- package/dist/presentation/PresentControls.d.ts +11 -0
- package/dist/presentation/PresentControls.js +117 -0
- package/dist/presentation/PresentControls.js.map +7 -0
- package/dist/presentation/PresentationStage.d.ts +32 -0
- package/dist/presentation/PresentationStage.js +232 -0
- package/dist/presentation/PresentationStage.js.map +7 -0
- package/dist/presentation/PresenterView.d.ts +16 -0
- package/dist/presentation/PresenterView.js +100 -0
- package/dist/presentation/PresenterView.js.map +7 -0
- package/dist/presentation/SlideDecor.d.ts +25 -0
- package/dist/presentation/SlideDecor.js +189 -0
- package/dist/presentation/SlideDecor.js.map +7 -0
- package/dist/presentation/SlidesEditor.d.ts +25 -0
- package/dist/presentation/SlidesEditor.js +375 -0
- package/dist/presentation/SlidesEditor.js.map +7 -0
- package/dist/presentation/StageBox.d.ts +30 -0
- package/dist/presentation/StageBox.js +281 -0
- package/dist/presentation/StageBox.js.map +7 -0
- package/dist/presentation/StageItem.d.ts +37 -0
- package/dist/presentation/StageItem.js +211 -0
- package/dist/presentation/StageItem.js.map +7 -0
- package/dist/presentation/box-style.d.ts +6 -0
- package/dist/presentation/box-style.js +19 -0
- package/dist/presentation/box-style.js.map +7 -0
- package/dist/presentation/boxes.d.ts +105 -0
- package/dist/presentation/boxes.js +103 -0
- package/dist/presentation/boxes.js.map +7 -0
- package/dist/presentation/draw-boxes.d.ts +8 -0
- package/dist/presentation/draw-boxes.js +130 -0
- package/dist/presentation/draw-boxes.js.map +7 -0
- package/dist/presentation/export-boxes.d.ts +10 -0
- package/dist/presentation/export-boxes.js +74 -0
- package/dist/presentation/export-boxes.js.map +7 -0
- package/dist/presentation/export-pptx.d.ts +16 -0
- package/dist/presentation/export-pptx.js +194 -0
- package/dist/presentation/export-pptx.js.map +7 -0
- package/dist/presentation/import-pptx.d.ts +35 -0
- package/dist/presentation/import-pptx.js +659 -0
- package/dist/presentation/import-pptx.js.map +7 -0
- package/dist/presentation/merge-outside-edits.d.ts +12 -0
- package/dist/presentation/merge-outside-edits.js +35 -0
- package/dist/presentation/merge-outside-edits.js.map +7 -0
- package/dist/presentation/model.d.ts +201 -0
- package/dist/presentation/model.js +271 -0
- package/dist/presentation/model.js.map +7 -0
- package/dist/presentation/panel-id.d.ts +44 -0
- package/dist/presentation/panel-id.js +29 -0
- package/dist/presentation/panel-id.js.map +7 -0
- package/dist/presentation/persistence.d.ts +121 -0
- package/dist/presentation/persistence.js +141 -0
- package/dist/presentation/persistence.js.map +7 -0
- package/dist/presentation/pptx-data.d.ts +22 -0
- package/dist/presentation/pptx-data.js +83 -0
- package/dist/presentation/pptx-data.js.map +7 -0
- package/dist/presentation/pptx-xml.d.ts +90 -0
- package/dist/presentation/pptx-xml.js +333 -0
- package/dist/presentation/pptx-xml.js.map +7 -0
- package/dist/presentation/render-slides.d.ts +58 -0
- package/dist/presentation/render-slides.js +309 -0
- package/dist/presentation/render-slides.js.map +7 -0
- package/dist/presentation/saved-boxes.d.ts +11 -0
- package/dist/presentation/saved-boxes.js +80 -0
- package/dist/presentation/saved-boxes.js.map +7 -0
- package/dist/presentation/slide-layout.d.ts +58 -0
- package/dist/presentation/slide-layout.js +133 -0
- package/dist/presentation/slide-layout.js.map +7 -0
- package/dist/presentation/stage-videos.d.ts +5 -0
- package/dist/presentation/stage-videos.js +19 -0
- package/dist/presentation/stage-videos.js.map +7 -0
- package/dist/presentation/store.d.ts +203 -0
- package/dist/presentation/store.js +429 -0
- package/dist/presentation/store.js.map +7 -0
- package/dist/presentation/theme.d.ts +102 -0
- package/dist/presentation/theme.js +276 -0
- package/dist/presentation/theme.js.map +7 -0
- package/dist/presentation/useClipDrag.d.ts +26 -0
- package/dist/presentation/useClipDrag.js +65 -0
- package/dist/presentation/useClipDrag.js.map +7 -0
- package/dist/presentation/useObjectUrl.d.ts +6 -0
- package/dist/presentation/useObjectUrl.js +15 -0
- package/dist/presentation/useObjectUrl.js.map +7 -0
- package/dist/presentation/usePresenterKeys.d.ts +13 -0
- package/dist/presentation/usePresenterKeys.js +62 -0
- package/dist/presentation/usePresenterKeys.js.map +7 -0
- package/dist/settings/index.cjs +149 -148
- package/dist/shell/PanelPortal.js +13 -3
- package/dist/shell/PanelPortal.js.map +2 -2
- package/dist/shell/index.cjs +49 -46
- package/dist/shell/panel-windows.d.ts +2 -0
- package/dist/shell/panel-windows.js +8 -2
- package/dist/shell/panel-windows.js.map +2 -2
- package/dist/studio/index.cjs +8 -6
- package/dist/studio/index.cjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/workflow-canvas/index.cjs +26 -25
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +6 -5
- package/dist/ConnectedCallDock-WER7R222.cjs.map +0 -1
- package/dist/DocumentReviewCard-BPIAJJED.cjs.map +0 -1
- package/dist/FilesViewerDialog-67WK3TZC.cjs.map +0 -1
- package/dist/GridViewImpl-ZMJJWTOM.cjs.map +0 -1
- package/dist/WorkspaceTableView-J3C6VH4T.cjs.map +0 -1
- package/dist/ai-IM4A23YT.cjs.map +0 -1
- package/dist/chunk-557MJ4IH.cjs.map +0 -1
- package/dist/chunk-6UTKM5AB.cjs.map +0 -1
- package/dist/chunk-6WMMZLEV.cjs.map +0 -1
- package/dist/chunk-B3LZITVF.cjs.map +0 -1
- package/dist/chunk-BUVIBHFU.cjs.map +0 -1
- package/dist/chunk-CKCG4NDB.cjs.map +0 -1
- package/dist/chunk-CPR6EHG7.cjs.map +0 -1
- package/dist/chunk-HA66DHW6.cjs.map +0 -1
- package/dist/chunk-NJCK6V6U.cjs.map +0 -1
- package/dist/chunk-NLSWDP42.cjs.map +0 -1
- package/dist/chunk-PGJYD67F.cjs.map +0 -1
- package/dist/chunk-X36UR4A7.cjs.map +0 -1
- package/dist/chunk-YYPZOEED.cjs.map +0 -1
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { create } from "zustand";
|
|
3
|
+
import { releasePdfRegionSource } from "@arbidocs/react/viewers";
|
|
4
|
+
import {
|
|
5
|
+
alignFrame,
|
|
6
|
+
autoLayout,
|
|
7
|
+
defaultCaption,
|
|
8
|
+
dropFrame,
|
|
9
|
+
fitFrame,
|
|
10
|
+
fullHeightFrame,
|
|
11
|
+
fullWidthFrame,
|
|
12
|
+
moveFrame
|
|
13
|
+
} from "./model.js";
|
|
14
|
+
import { slideGeometry } from "./slide-layout.js";
|
|
15
|
+
import { DEFAULT_THEME } from "./theme.js";
|
|
16
|
+
import { serializePresentation } from "./persistence.js";
|
|
17
|
+
import { nextBoxId, withText } from "./boxes.js";
|
|
18
|
+
const MIN_CLIP_AREA = 0.02;
|
|
19
|
+
const MAX_ITEMS_PER_SLIDE = 6;
|
|
20
|
+
const AUTO_PLACE_BELOW = 2;
|
|
21
|
+
let sequence = 0;
|
|
22
|
+
const nextId = (kind) => `${kind}-${Date.now().toString(36)}-${++sequence}`;
|
|
23
|
+
const emptySlide = (layout = "clips") => ({
|
|
24
|
+
id: nextId("slide"),
|
|
25
|
+
items: [],
|
|
26
|
+
auto: true,
|
|
27
|
+
caption: "",
|
|
28
|
+
layout,
|
|
29
|
+
points: "",
|
|
30
|
+
boxes: []
|
|
31
|
+
});
|
|
32
|
+
const initialState = () => ({
|
|
33
|
+
clips: [],
|
|
34
|
+
slides: [emptySlide()],
|
|
35
|
+
current: 0,
|
|
36
|
+
blank: false,
|
|
37
|
+
captions: true,
|
|
38
|
+
theme: DEFAULT_THEME,
|
|
39
|
+
logoImage: null,
|
|
40
|
+
labelColumn: null,
|
|
41
|
+
columnValues: {},
|
|
42
|
+
presenting: false,
|
|
43
|
+
dragging: null,
|
|
44
|
+
notice: null,
|
|
45
|
+
title: "Untitled presentation",
|
|
46
|
+
savedId: null,
|
|
47
|
+
version: null,
|
|
48
|
+
boundTo: null,
|
|
49
|
+
clean: null,
|
|
50
|
+
media: {}
|
|
51
|
+
});
|
|
52
|
+
function arranged(slide, clips, look) {
|
|
53
|
+
const aspects = slide.items.map((item) => aspectOf(clips, item.clipId));
|
|
54
|
+
const frames = autoLayout(aspects, reserveOf(slide, look));
|
|
55
|
+
return {
|
|
56
|
+
...slide,
|
|
57
|
+
auto: true,
|
|
58
|
+
items: slide.items.map((item, i) => ({ ...item, frame: frames[i] }))
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const reserveOf = (slide, look) => slideGeometry(slide, { labels: look.captions, logo: look.theme.logo?.corner ?? null }).reserve;
|
|
62
|
+
function aspectOf(clips, clipId) {
|
|
63
|
+
return clips.find((clip) => clip.id === clipId)?.aspect ?? 1;
|
|
64
|
+
}
|
|
65
|
+
const usePresentation = create()((set, get) => {
|
|
66
|
+
const updateSlide = (change, at) => set((state) => {
|
|
67
|
+
const index = at ?? state.current;
|
|
68
|
+
const slide = state.slides[index];
|
|
69
|
+
if (!slide) return state;
|
|
70
|
+
const next = change(slide, state.clips);
|
|
71
|
+
if (next === slide) return state;
|
|
72
|
+
const slides = state.slides.slice();
|
|
73
|
+
slides[index] = next.auto ? arranged(next, state.clips, state) : next;
|
|
74
|
+
return { slides };
|
|
75
|
+
});
|
|
76
|
+
const updateBoxes = (boxId, change) => set((state) => {
|
|
77
|
+
const index = state.slides.findIndex((slide2) => slide2.boxes.some((box) => box.id === boxId));
|
|
78
|
+
if (index < 0) return state;
|
|
79
|
+
const slide = state.slides[index];
|
|
80
|
+
const slides = state.slides.slice();
|
|
81
|
+
slides[index] = {
|
|
82
|
+
...slide,
|
|
83
|
+
boxes: change(
|
|
84
|
+
slide.boxes,
|
|
85
|
+
slide.boxes.findIndex((box) => box.id === boxId)
|
|
86
|
+
)
|
|
87
|
+
};
|
|
88
|
+
return { slides };
|
|
89
|
+
});
|
|
90
|
+
const restack = (clipId, to) => set((state) => {
|
|
91
|
+
const slide = state.slides[state.current];
|
|
92
|
+
const item = slide?.items.find((entry) => entry.clipId === clipId);
|
|
93
|
+
if (!slide || !item) return state;
|
|
94
|
+
const rest = slide.items.filter((entry) => entry !== item);
|
|
95
|
+
const items = to === "front" ? [...rest, item] : [item, ...rest];
|
|
96
|
+
if (items.every((entry, i) => entry === slide.items[i])) return state;
|
|
97
|
+
const slides = state.slides.slice();
|
|
98
|
+
slides[state.current] = { ...slide, items };
|
|
99
|
+
return { slides };
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
...initialState(),
|
|
103
|
+
addClip(clip) {
|
|
104
|
+
const id = nextId("clip");
|
|
105
|
+
const full = {
|
|
106
|
+
...clip,
|
|
107
|
+
id,
|
|
108
|
+
caption: clip.caption ?? defaultCaption(clip.fileName, clip.page),
|
|
109
|
+
zoomBase: clip.zoomBase ?? clip.rect.w
|
|
110
|
+
};
|
|
111
|
+
set((state) => ({ clips: [...state.clips, full] }));
|
|
112
|
+
const slide = get().slides[get().current];
|
|
113
|
+
if (slide && slide.items.length < AUTO_PLACE_BELOW) get().place(id);
|
|
114
|
+
return id;
|
|
115
|
+
},
|
|
116
|
+
removeClip(clipId) {
|
|
117
|
+
const { clips, slides } = get();
|
|
118
|
+
const removed = clips.find((clip) => clip.id === clipId);
|
|
119
|
+
if (!removed) return;
|
|
120
|
+
const rest = clips.filter((clip) => clip.id !== clipId);
|
|
121
|
+
set({
|
|
122
|
+
clips: rest,
|
|
123
|
+
slides: slides.map((slide) => {
|
|
124
|
+
if (!slide.items.some((item) => item.clipId === clipId)) return slide;
|
|
125
|
+
const next = { ...slide, items: slide.items.filter((item) => item.clipId !== clipId) };
|
|
126
|
+
return next.auto ? arranged(next, rest, get()) : next;
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
if (!rest.some((clip) => clip.source === removed.source))
|
|
130
|
+
releasePdfRegionSource(removed.source);
|
|
131
|
+
},
|
|
132
|
+
setCaption: (clipId, caption) => set((state) => ({
|
|
133
|
+
clips: state.clips.map((clip) => clip.id === clipId ? { ...clip, caption } : clip)
|
|
134
|
+
})),
|
|
135
|
+
place: (clipId, at) => updateSlide((slide, clips) => {
|
|
136
|
+
if (!clips.some((clip) => clip.id === clipId)) return slide;
|
|
137
|
+
const others = slide.items.filter((item) => item.clipId !== clipId);
|
|
138
|
+
if (!at && others.length < slide.items.length) return slide;
|
|
139
|
+
if (others.length >= MAX_ITEMS_PER_SLIDE) return slide;
|
|
140
|
+
const aspect = aspectOf(clips, clipId);
|
|
141
|
+
const frame = slide.auto ? fitFrame(aspect) : dropFrame(aspect, at ?? { x: 0.5, y: 0.5 });
|
|
142
|
+
return { ...slide, items: [...others, { clipId, frame }] };
|
|
143
|
+
}),
|
|
144
|
+
unplace: (clipId) => updateSlide(
|
|
145
|
+
(slide) => slide.items.some((item) => item.clipId === clipId) ? { ...slide, items: slide.items.filter((item) => item.clipId !== clipId) } : slide
|
|
146
|
+
),
|
|
147
|
+
setFrame: (clipId, frame) => updateSlide((slide) => ({
|
|
148
|
+
...slide,
|
|
149
|
+
auto: false,
|
|
150
|
+
items: slide.items.map((item) => item.clipId === clipId ? { ...item, frame } : item)
|
|
151
|
+
})),
|
|
152
|
+
applyFrame(clipId, command) {
|
|
153
|
+
const slide = get().slides[get().current];
|
|
154
|
+
const item = slide?.items.find((entry) => entry.clipId === clipId);
|
|
155
|
+
if (!item) return;
|
|
156
|
+
const aspect = aspectOf(get().clips, clipId);
|
|
157
|
+
const reserve = reserveOf(slide, get());
|
|
158
|
+
const frame = command === "fullWidth" ? fullWidthFrame(item.frame, aspect, reserve) : command === "fullHeight" ? fullHeightFrame(item.frame, aspect, reserve) : fitFrame(aspect, reserve);
|
|
159
|
+
get().setFrame(clipId, frame);
|
|
160
|
+
get().bringToFront(clipId);
|
|
161
|
+
},
|
|
162
|
+
bringToFront: (clipId) => restack(clipId, "front"),
|
|
163
|
+
sendToBack: (clipId) => restack(clipId, "back"),
|
|
164
|
+
panClip: (clipId, dx, dy) => set((state) => {
|
|
165
|
+
const clip = state.clips.find((entry) => entry.id === clipId);
|
|
166
|
+
if (!clip) return state;
|
|
167
|
+
const { rect } = clip;
|
|
168
|
+
const x = Math.min(Math.max(rect.x + dx, 0), 1 - rect.w);
|
|
169
|
+
const y = Math.min(Math.max(rect.y + dy, 0), 1 - rect.h);
|
|
170
|
+
if (x === rect.x && y === rect.y) return state;
|
|
171
|
+
return {
|
|
172
|
+
clips: state.clips.map(
|
|
173
|
+
(entry) => entry === clip ? { ...clip, rect: { ...rect, x, y } } : entry
|
|
174
|
+
)
|
|
175
|
+
};
|
|
176
|
+
}),
|
|
177
|
+
zoomClip: (clipId, factor) => set((state) => {
|
|
178
|
+
const clip = state.clips.find((entry) => entry.id === clipId);
|
|
179
|
+
if (!clip || !(factor > 0)) return state;
|
|
180
|
+
const { rect } = clip;
|
|
181
|
+
const largest = Math.min(1 / rect.w, 1 / rect.h);
|
|
182
|
+
const smallest = Math.max(MIN_CLIP_AREA / rect.w, MIN_CLIP_AREA / rect.h);
|
|
183
|
+
const scale = Math.min(Math.max(1 / factor, smallest), largest);
|
|
184
|
+
if (scale === 1) return state;
|
|
185
|
+
const w = rect.w * scale;
|
|
186
|
+
const h = rect.h * scale;
|
|
187
|
+
const x = Math.min(Math.max(rect.x + (rect.w - w) / 2, 0), 1 - w);
|
|
188
|
+
const y = Math.min(Math.max(rect.y + (rect.h - h) / 2, 0), 1 - h);
|
|
189
|
+
return {
|
|
190
|
+
clips: state.clips.map(
|
|
191
|
+
(entry) => entry === clip ? { ...clip, rect: { x, y, w, h } } : entry
|
|
192
|
+
)
|
|
193
|
+
};
|
|
194
|
+
}),
|
|
195
|
+
setClipZoom(clipId, percent) {
|
|
196
|
+
const clip = get().clips.find((entry) => entry.id === clipId);
|
|
197
|
+
if (!clip || !(percent > 0)) return;
|
|
198
|
+
const width = (clip.zoomBase ?? clip.rect.w) / (percent / 100);
|
|
199
|
+
get().zoomClip(clipId, clip.rect.w / width);
|
|
200
|
+
},
|
|
201
|
+
align(clipId, alignment) {
|
|
202
|
+
const slide = get().slides[get().current];
|
|
203
|
+
const item = slide?.items.find((entry) => entry.clipId === clipId);
|
|
204
|
+
if (!slide || !item) return;
|
|
205
|
+
const aspect = aspectOf(get().clips, clipId);
|
|
206
|
+
get().setFrame(clipId, alignFrame(item.frame, aspect, alignment, reserveOf(slide, get())));
|
|
207
|
+
},
|
|
208
|
+
nudge(clipId, dx, dy) {
|
|
209
|
+
const slide = get().slides[get().current];
|
|
210
|
+
const item = slide?.items.find((entry) => entry.clipId === clipId);
|
|
211
|
+
if (!item) return;
|
|
212
|
+
const aspect = aspectOf(get().clips, clipId);
|
|
213
|
+
get().setFrame(clipId, moveFrame(item.frame, aspect, dx, dy, [], true).frame);
|
|
214
|
+
},
|
|
215
|
+
// An auto slide makes (or gives back) the caption's room; one arranged by hand keeps its places.
|
|
216
|
+
// A blank slide's title is its title box's text.
|
|
217
|
+
setSlideCaption: (caption, index) => updateSlide(
|
|
218
|
+
(slide) => ({
|
|
219
|
+
...slide,
|
|
220
|
+
caption,
|
|
221
|
+
boxes: slide.boxes.map((box) => box.role === "title" ? withText(box, caption) : box)
|
|
222
|
+
}),
|
|
223
|
+
index
|
|
224
|
+
),
|
|
225
|
+
setSlideLayout: (layout, index) => updateSlide((slide) => ({ ...slide, layout, auto: true }), index),
|
|
226
|
+
setSlidePoints: (points, index) => updateSlide((slide) => ({ ...slide, points }), index),
|
|
227
|
+
setTheme: (change) => set((state) => {
|
|
228
|
+
const theme = { ...state.theme, ...change };
|
|
229
|
+
const logoMoved = (theme.logo?.corner ?? null) !== (state.theme.logo?.corner ?? null);
|
|
230
|
+
return {
|
|
231
|
+
theme,
|
|
232
|
+
...theme.logo?.documentId !== state.theme.logo?.documentId ? { logoImage: null } : {},
|
|
233
|
+
slides: logoMoved ? state.slides.map(
|
|
234
|
+
(slide) => slide.auto ? arranged(slide, state.clips, { ...state, theme }) : slide
|
|
235
|
+
) : state.slides
|
|
236
|
+
};
|
|
237
|
+
}),
|
|
238
|
+
setLogoImage: (logoImage) => set({ logoImage }),
|
|
239
|
+
arrange: () => updateSlide((slide) => ({ ...slide, auto: true })),
|
|
240
|
+
addSlide: (layout, after) => set((state) => {
|
|
241
|
+
const at = (after ?? state.current) + 1;
|
|
242
|
+
const slides = state.slides.slice();
|
|
243
|
+
const before = state.slides[at - 1];
|
|
244
|
+
const slide = emptySlide(layout ?? before?.layout ?? "clips");
|
|
245
|
+
slides.splice(
|
|
246
|
+
at,
|
|
247
|
+
0,
|
|
248
|
+
before?.background ? { ...slide, background: before.background } : slide
|
|
249
|
+
);
|
|
250
|
+
return { slides, current: at };
|
|
251
|
+
}),
|
|
252
|
+
removeSlide: (index) => set((state) => {
|
|
253
|
+
const target = index ?? state.current;
|
|
254
|
+
if (state.slides.length <= 1) return { slides: [emptySlide()], current: 0 };
|
|
255
|
+
const slides = state.slides.filter((_, i) => i !== target);
|
|
256
|
+
const current = state.current > target ? state.current - 1 : state.current;
|
|
257
|
+
return { slides, current: Math.min(current, slides.length - 1) };
|
|
258
|
+
}),
|
|
259
|
+
duplicateSlide: (index) => set((state) => {
|
|
260
|
+
const slide = state.slides[index];
|
|
261
|
+
if (!slide) return state;
|
|
262
|
+
const slides = state.slides.slice();
|
|
263
|
+
slides.splice(index + 1, 0, {
|
|
264
|
+
...slide,
|
|
265
|
+
id: nextId("slide"),
|
|
266
|
+
items: slide.items.map((item) => ({ ...item, frame: { ...item.frame } })),
|
|
267
|
+
boxes: slide.boxes.map((box) => ({ ...box, id: nextBoxId() }))
|
|
268
|
+
});
|
|
269
|
+
return { slides, current: index + 1 };
|
|
270
|
+
}),
|
|
271
|
+
moveSlide: (index, to) => set((state) => {
|
|
272
|
+
if (to < 0 || to >= state.slides.length || index === to || !state.slides[index]) {
|
|
273
|
+
return state;
|
|
274
|
+
}
|
|
275
|
+
const slides = state.slides.slice();
|
|
276
|
+
const [slide] = slides.splice(index, 1);
|
|
277
|
+
slides.splice(to, 0, slide);
|
|
278
|
+
return { slides, current: to };
|
|
279
|
+
}),
|
|
280
|
+
goTo: (index) => set(
|
|
281
|
+
(state) => index < 0 || index >= state.slides.length || index === state.current ? state : { current: index }
|
|
282
|
+
),
|
|
283
|
+
setBlank: (blank) => set({ blank }),
|
|
284
|
+
// Slides arranged automatically make (or give back) the captions' room.
|
|
285
|
+
setCaptions: (captions) => set((state) => ({
|
|
286
|
+
captions,
|
|
287
|
+
slides: state.slides.map(
|
|
288
|
+
(slide) => slide.auto ? arranged(slide, state.clips, { ...state, captions }) : slide
|
|
289
|
+
)
|
|
290
|
+
})),
|
|
291
|
+
setLabelColumn: (labelColumn) => set({ labelColumn }),
|
|
292
|
+
setColumnValues: (columnValues) => set({ columnValues }),
|
|
293
|
+
setPresenting: (presenting) => set({ presenting }),
|
|
294
|
+
setDragging: (dragging) => set({ dragging }),
|
|
295
|
+
setTitle: (title) => set({ title }),
|
|
296
|
+
notify: (text, kind) => set({ notice: { text, kind, id: ++sequence } }),
|
|
297
|
+
clearNotice: (id) => set((state) => state.notice?.id === id ? { notice: null } : state),
|
|
298
|
+
cropClip: (clipId, rect, aspect) => set((state) => {
|
|
299
|
+
const clips = state.clips.map(
|
|
300
|
+
(clip) => clip.id === clipId ? { ...clip, rect, aspect } : clip
|
|
301
|
+
);
|
|
302
|
+
return {
|
|
303
|
+
clips,
|
|
304
|
+
// Its shape changed: slides arranged automatically arrange again around it.
|
|
305
|
+
slides: state.slides.map(
|
|
306
|
+
(slide) => slide.auto && slide.items.some((item) => item.clipId === clipId) ? arranged(slide, clips, state) : slide
|
|
307
|
+
)
|
|
308
|
+
};
|
|
309
|
+
}),
|
|
310
|
+
reshapeClip: (clipId, frame, rect, aspect) => set((state) => {
|
|
311
|
+
const clip = state.clips.find((entry) => entry.id === clipId);
|
|
312
|
+
if (!clip) return state;
|
|
313
|
+
const zoomBase = (clip.zoomBase ?? clip.rect.w) * rect.w / clip.rect.w;
|
|
314
|
+
const clips = state.clips.map(
|
|
315
|
+
(entry) => entry === clip ? { ...clip, rect, aspect, zoomBase } : entry
|
|
316
|
+
);
|
|
317
|
+
return {
|
|
318
|
+
clips,
|
|
319
|
+
slides: state.slides.map((slide, index) => {
|
|
320
|
+
if (index === state.current) {
|
|
321
|
+
return {
|
|
322
|
+
...slide,
|
|
323
|
+
auto: false,
|
|
324
|
+
items: slide.items.map(
|
|
325
|
+
(item) => item.clipId === clipId ? { ...item, frame } : item
|
|
326
|
+
)
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
return slide.auto && slide.items.some((item) => item.clipId === clipId) ? arranged(slide, clips, state) : slide;
|
|
330
|
+
})
|
|
331
|
+
};
|
|
332
|
+
}),
|
|
333
|
+
addBox(box, index) {
|
|
334
|
+
const id = nextBoxId();
|
|
335
|
+
updateSlide((slide) => ({ ...slide, boxes: [...slide.boxes, { ...box, id }] }), index);
|
|
336
|
+
return id;
|
|
337
|
+
},
|
|
338
|
+
updateBox: (boxId, change) => updateBoxes(boxId, (boxes, at) => {
|
|
339
|
+
const next = boxes.slice();
|
|
340
|
+
next[at] = change(boxes[at]);
|
|
341
|
+
return next;
|
|
342
|
+
}),
|
|
343
|
+
setBoxText(boxId, text) {
|
|
344
|
+
get().updateBox(boxId, (box) => withText(box, text));
|
|
345
|
+
set((state) => ({
|
|
346
|
+
slides: state.slides.map(
|
|
347
|
+
(slide) => slide.boxes.some((box) => box.id === boxId && box.role === "title") ? { ...slide, caption: text.replace(/\s*\n\s*/g, " ").trim() } : slide
|
|
348
|
+
)
|
|
349
|
+
}));
|
|
350
|
+
},
|
|
351
|
+
removeBox: (boxId) => updateBoxes(boxId, (boxes, at) => boxes.filter((_, i) => i !== at)),
|
|
352
|
+
restackBox: (boxId, to) => updateBoxes(boxId, (boxes, at) => {
|
|
353
|
+
const box = { ...boxes[at], front: to === "front" };
|
|
354
|
+
const rest = boxes.filter((_, i) => i !== at);
|
|
355
|
+
return to === "front" ? [...rest, box] : [box, ...rest];
|
|
356
|
+
}),
|
|
357
|
+
setSlideNotes: (notes, index) => updateSlide((slide) => ({ ...slide, notes }), index),
|
|
358
|
+
setSlideBackground: (background, index) => updateSlide((slide) => {
|
|
359
|
+
const { background: _old, ...rest } = slide;
|
|
360
|
+
void _old;
|
|
361
|
+
return background ? { ...rest, background } : rest;
|
|
362
|
+
}, index),
|
|
363
|
+
setSaved: (savedId, title, version = null) => {
|
|
364
|
+
set({ savedId, title, boundTo: savedId, version });
|
|
365
|
+
set({ clean: snapshotOf(get()) });
|
|
366
|
+
},
|
|
367
|
+
bind: (boundTo) => set({ boundTo }),
|
|
368
|
+
adoptClips: (adopted) => set((state) => ({
|
|
369
|
+
clips: [
|
|
370
|
+
...state.clips,
|
|
371
|
+
...adopted.filter((clip) => !state.clips.some((entry) => entry.id === clip.id))
|
|
372
|
+
]
|
|
373
|
+
})),
|
|
374
|
+
load(opened) {
|
|
375
|
+
get().reset();
|
|
376
|
+
const clips = opened.clips.map((clip) => ({ ...clip, id: nextId("clip") }));
|
|
377
|
+
const slides = opened.slides.map((slide) => ({
|
|
378
|
+
id: nextId("slide"),
|
|
379
|
+
caption: slide.caption,
|
|
380
|
+
auto: slide.auto,
|
|
381
|
+
layout: slide.layout ?? "clips",
|
|
382
|
+
points: slide.points ?? "",
|
|
383
|
+
// Items whose clip could not be opened are left out.
|
|
384
|
+
items: slide.items.filter((item) => clips[item.clip]).map((item) => ({ clipId: clips[item.clip].id, frame: item.frame })),
|
|
385
|
+
boxes: (slide.boxes ?? []).map((box) => ({ ...box, id: nextBoxId() })),
|
|
386
|
+
...slide.background ? { background: slide.background } : {},
|
|
387
|
+
...slide.notes ? { notes: slide.notes } : {}
|
|
388
|
+
}));
|
|
389
|
+
set({
|
|
390
|
+
title: opened.title,
|
|
391
|
+
savedId: opened.savedId,
|
|
392
|
+
version: opened.version ?? null,
|
|
393
|
+
boundTo: opened.boundTo ?? opened.savedId,
|
|
394
|
+
captions: opened.captions,
|
|
395
|
+
labelColumn: opened.labelColumn ?? null,
|
|
396
|
+
theme: opened.theme ?? DEFAULT_THEME,
|
|
397
|
+
clips,
|
|
398
|
+
slides: slides.length ? slides : [emptySlide()],
|
|
399
|
+
current: 0,
|
|
400
|
+
media: opened.media ?? {}
|
|
401
|
+
});
|
|
402
|
+
set({ clean: opened.savedId ? snapshotOf(get()) : null });
|
|
403
|
+
},
|
|
404
|
+
reset() {
|
|
405
|
+
for (const source of new Set(get().clips.map((clip) => clip.source))) {
|
|
406
|
+
releasePdfRegionSource(source);
|
|
407
|
+
}
|
|
408
|
+
set(initialState());
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
});
|
|
412
|
+
const currentSlide = (state) => state.slides[state.current];
|
|
413
|
+
function snapshotOf(state) {
|
|
414
|
+
return JSON.stringify(serializePresentation({ ...state, media: void 0 }));
|
|
415
|
+
}
|
|
416
|
+
function hasUnsavedChanges(state) {
|
|
417
|
+
if (state.clean !== null) return snapshotOf(state) !== state.clean;
|
|
418
|
+
return state.clips.length > 0 || state.slides.some(
|
|
419
|
+
(slide) => slide.items.length || slide.boxes.length || slide.caption.trim() || slide.points.trim()
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
export {
|
|
423
|
+
MAX_ITEMS_PER_SLIDE,
|
|
424
|
+
currentSlide,
|
|
425
|
+
hasUnsavedChanges,
|
|
426
|
+
reserveOf,
|
|
427
|
+
usePresentation
|
|
428
|
+
};
|
|
429
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/presentation/store.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The presentation of this session: the clips taken, the slides they are arranged on, the slide on\n * the stage, whether the stage is blanked and whether the presentation window presents (shows only\n * the stage, for sharing) or edits. Clips taken in the app's viewer land in it at once.\n *\n * Kept in memory only: a clip holds the decrypted PDF it is drawn from, so nothing is written to\n * storage, and everything is cleared when the session signs out (`ConnectedPresentation`).\n */\n\nimport { create } from 'zustand'\nimport { releasePdfRegionSource } from '@arbidocs/react/viewers'\nimport {\n alignFrame,\n autoLayout,\n defaultCaption,\n dropFrame,\n fitFrame,\n fullHeightFrame,\n fullWidthFrame,\n moveFrame,\n type Alignment,\n type Clip,\n type Rect,\n type Reserve,\n type Frame,\n type Slide,\n type SlideLayout,\n} from './model'\nimport { slideGeometry } from './slide-layout'\nimport { DEFAULT_THEME, type Theme } from './theme'\nimport { serializePresentation } from './persistence'\nimport { nextBoxId, withText, type SlideBackground, type SlideBox } from './boxes'\nimport type { SavedBox } from './saved-boxes'\n\n/** The smallest a clip's area can be zoomed to (a fraction of its source, either side). */\nconst MIN_CLIP_AREA = 0.02\n\n/** A slide holds a handful of clips: more would be too small to read on a shared screen. */\nexport const MAX_ITEMS_PER_SLIDE = 6\n/** A new clip goes on the slide by itself while the slide has fewer than this. */\nconst AUTO_PLACE_BELOW = 2\n\nexport type NewClip = Omit<Clip, 'id' | 'caption'> & { caption?: string }\nexport type FrameCommand = 'fullWidth' | 'fullHeight' | 'fit'\n\ninterface PresentationState {\n clips: Clip[]\n slides: Slide[]\n /** Index of the slide on the stage. */\n current: number\n /** The stage shows nothing (black) while true. */\n blank: boolean\n captions: boolean\n /** One look for every slide: background, typeface, accent, logo. Saved. */\n theme: Theme\n /** The theme's logo image (this session only; fetched by the host from `theme.logo`). */\n logoImage: Blob | null\n /**\n * The annotation column (a tag's id) whose value for each clip's document leads its label: an\n * Exhibit column's \"R-100\". Saved with the presentation.\n */\n labelColumn: string | null\n /** Each clip document's value in `labelColumn`, kept current by the host (not saved). */\n columnValues: Readonly<Record<string, string>>\n /** Present mode: the presentation window shows only the stage (what is shared). */\n presenting: boolean\n /** The presentation's name (its file's, once saved). */\n title: string\n /** The document it is saved as, once saved: saving again adds a version to it. */\n savedId: string | null\n /** Which version of that document this is (as opened or saved), when known. */\n version: number | null\n /**\n * The document (or draft) this presentation is edited as, in the viewer: its slides tab shows\n * it. Null: clips gathered with no presentation open yet (a new one takes them).\n */\n boundTo: string | null\n /** The presentation as last opened or saved (serialised), to tell unsaved changes; null: never. */\n clean: string | null\n /**\n * A message for the presentation window itself (saved, failed\u2026): the app's notifications show in\n * the app's window, out of sight behind a popped-out presentation.\n */\n notice: { text: string; kind: 'success' | 'error'; id: number } | null\n /** The clip being dragged from the tray, while it is (the drop targets light up). */\n dragging: string | null\n /** Images embedded in the presentation (an imported deck's pictures), as data URLs, by key. */\n media: Readonly<Record<string, string>>\n}\n\ninterface PresentationActions {\n /** Add a clip; it is placed on the current slide while that has fewer than two. */\n addClip(clip: NewClip): string\n removeClip(clipId: string): void\n setCaption(clipId: string, caption: string): void\n /** Put a clip on the current slide (at a point, when dropped there). */\n place(clipId: string, at?: { x: number; y: number }): void\n unplace(clipId: string): void\n /** Move or resize a clip by hand: the slide stops arranging itself. */\n setFrame(clipId: string, frame: Frame): void\n applyFrame(clipId: string, command: FrameCommand): void\n /** Overlapping clips: this one on top of the others (later items are drawn over earlier ones). */\n bringToFront(clipId: string): void\n /** Overlapping clips: this one under the others. */\n sendToBack(clipId: string): void\n /**\n * Scroll what a clip shows over its page, image or video by `dx, dy` (fractions of the source),\n * its size kept and kept within the source: e.g. to show the lines above or below a passage.\n */\n panClip(clipId: string, dx: number, dy: number): void\n /**\n * Zoom what a clip shows by `factor` (2: twice as close) about its centre: its area over the\n * source shrinks or grows, its shape kept, never past the source's edges.\n */\n zoomClip(clipId: string, factor: number): void\n /** Zoom a clip to `percent` of how close it was cut (100: as cut), about its centre. */\n setClipZoom(clipId: string, percent: number): void\n /** Align a clip on the stage (inside the margins and the slide's reserved room). */\n align(clipId: string, alignment: Alignment): void\n /** Nudge a clip by `dx, dy` (stage fractions), kept on the stage, not snapped. */\n nudge(clipId: string, dx: number, dy: number): void\n /** The current slide's caption (shown across its top; empty for none). */\n /** A slide's title (default the current slide's). */\n setSlideCaption(caption: string, index?: number): void\n /** The current slide's layout: it is arranged for it again. */\n setSlideLayout(layout: SlideLayout, index?: number): void\n /** The current slide's text (its points, or subtitle). */\n setSlidePoints(points: string, index?: number): void\n /** Change the theme; slides arranging themselves make room for a logo (or give it back). */\n setTheme(change: Partial<Theme>): void\n setLogoImage(image: Blob | null): void\n /** Arrange the current slide automatically again. */\n arrange(): void\n /** A new slide after the current one (by default with the current slide's layout). */\n addSlide(layout?: SlideLayout, after?: number): void\n /** Remove a slide (default the current one); the last one left is emptied instead. */\n removeSlide(index?: number): void\n /** A copy of a slide (its title, points and clips), right after it. */\n duplicateSlide(index: number): void\n /** Move a slide to `to` (the others shift up or down). */\n moveSlide(index: number, to: number): void\n goTo(index: number): void\n setBlank(blank: boolean): void\n setCaptions(captions: boolean): void\n setLabelColumn(tagId: string | null): void\n setColumnValues(values: Readonly<Record<string, string>>): void\n setPresenting(presenting: boolean): void\n setDragging(clipId: string | null): void\n setTitle(title: string): void\n notify(text: string, kind: 'success' | 'error'): void\n clearNotice(id: number): void\n /** Show another part of an image or video clip's source (a new crop): its area and shape. */\n cropClip(clipId: string, rect: Rect, aspect: number): void\n /**\n * A clip reshaped on the current slide (`reshapeFrame`): it shows `rect` of its source, in\n * `frame`, at the same scale and zoom. Slides arranging themselves arrange around its new shape.\n */\n reshapeClip(clipId: string, frame: Frame, rect: Rect, aspect: number): void\n /** A text box or shape on a slide (default the current one), on top; resolves with its id. */\n addBox(box: Omit<SlideBox, 'id'>, index?: number): string\n /** Change a box (wherever it is). */\n updateBox(boxId: string, change: (box: SlideBox) => SlideBox): void\n /** Type a box's text (one paragraph per line, each keeping its style). */\n setBoxText(boxId: string, text: string): void\n removeBox(boxId: string): void\n /** A box over the slide's clips and other boxes, or under them all. */\n restackBox(boxId: string, to: 'front' | 'back'): void\n /** A slide's speaker notes (default the current slide's). */\n setSlideNotes(notes: string, index?: number): void\n /** A slide's own background (none: the theme's). */\n setSlideBackground(background: SlideBackground | undefined, index?: number): void\n /** Saved as this document (under this title), as its `version`. */\n setSaved(savedId: string, title: string, version?: number | null): void\n /** Edited as this document or draft (see `boundTo`). */\n bind(boundTo: string | null): void\n /** Clips gathered before (with no presentation open), added to the tray, not placed. */\n adoptClips(clips: readonly Clip[]): void\n /** Replace the presentation with one opened from a file (its clips' sources fetched). */\n load(opened: {\n title: string\n /** The document it is saved as; null for a new one (from a template). */\n savedId: string | null\n /** Its version, when known. */\n version?: number | null\n /** Edited as (default `savedId`): an older file opened unsaved is still its own. */\n boundTo?: string | null\n captions: boolean\n labelColumn?: string | null\n theme?: Theme\n clips: Omit<Clip, 'id'>[]\n slides: {\n caption: string\n auto: boolean\n layout?: SlideLayout\n points?: string\n items: { clip: number; frame: Frame }[]\n boxes?: readonly SavedBox[]\n background?: SlideBackground\n notes?: string\n }[]\n media?: Readonly<Record<string, string>>\n }): void\n reset(): void\n}\n\nexport type PresentationStore = PresentationState & PresentationActions\n\nlet sequence = 0\nconst nextId = (kind: string) => `${kind}-${Date.now().toString(36)}-${++sequence}`\n\nconst emptySlide = (layout: SlideLayout = 'clips'): Slide => ({\n id: nextId('slide'),\n items: [],\n auto: true,\n caption: '',\n layout,\n points: '',\n boxes: [],\n})\n\nconst initialState = (): PresentationState => ({\n clips: [],\n slides: [emptySlide()],\n current: 0,\n blank: false,\n captions: true,\n theme: DEFAULT_THEME,\n logoImage: null,\n labelColumn: null,\n columnValues: {},\n presenting: false,\n dragging: null,\n notice: null,\n title: 'Untitled presentation',\n savedId: null,\n version: null,\n boundTo: null,\n clean: null,\n media: {},\n})\n\n/** What arranging a slide depends on besides its clips: labels shown, a logo in the footer. */\ntype Look = Pick<PresentationState, 'captions' | 'theme'>\n\n/** The slide arranged again from its clips' aspects, in the room its layout leaves them. */\nfunction arranged(slide: Slide, clips: readonly Clip[], look: Look): Slide {\n const aspects = slide.items.map((item) => aspectOf(clips, item.clipId))\n const frames = autoLayout(aspects, reserveOf(slide, look))\n return {\n ...slide,\n auto: true,\n items: slide.items.map((item, i) => ({ ...item, frame: frames[i] })),\n }\n}\n\n/**\n * The room a slide keeps free of clips: its title and text (by its layout), each clip's label\n * under it, the footer while a logo shows.\n */\nexport const reserveOf = (slide: Pick<Slide, 'caption' | 'layout'>, look: Look): Reserve =>\n slideGeometry(slide, { labels: look.captions, logo: look.theme.logo?.corner ?? null }).reserve\n\nfunction aspectOf(clips: readonly Clip[], clipId: string): number {\n return clips.find((clip) => clip.id === clipId)?.aspect ?? 1\n}\n\nexport const usePresentation = create<PresentationStore>()((set, get) => {\n /** Change the current slide; an auto slide is arranged again after the change. */\n const updateSlide = (change: (slide: Slide, clips: readonly Clip[]) => Slide, at?: number) =>\n set((state) => {\n const index = at ?? state.current\n const slide = state.slides[index]\n if (!slide) return state\n const next = change(slide, state.clips)\n if (next === slide) return state\n const slides = state.slides.slice()\n slides[index] = next.auto ? arranged(next, state.clips, state) : next\n return { slides }\n })\n\n /** Change the boxes of the slide holding `boxId` (`at`: the box's index there). */\n const updateBoxes = (\n boxId: string,\n change: (boxes: readonly SlideBox[], at: number) => SlideBox[]\n ) =>\n set((state) => {\n const index = state.slides.findIndex((slide) => slide.boxes.some((box) => box.id === boxId))\n if (index < 0) return state\n const slide = state.slides[index]\n const slides = state.slides.slice()\n slides[index] = {\n ...slide,\n boxes: change(\n slide.boxes,\n slide.boxes.findIndex((box) => box.id === boxId)\n ),\n }\n return { slides }\n })\n\n /** Restack a clip on the current slide: only the drawing order changes, never a position. */\n const restack = (clipId: string, to: 'front' | 'back') =>\n set((state) => {\n const slide = state.slides[state.current]\n const item = slide?.items.find((entry) => entry.clipId === clipId)\n if (!slide || !item) return state\n const rest = slide.items.filter((entry) => entry !== item)\n const items = to === 'front' ? [...rest, item] : [item, ...rest]\n if (items.every((entry, i) => entry === slide.items[i])) return state\n const slides = state.slides.slice()\n slides[state.current] = { ...slide, items }\n return { slides }\n })\n\n return {\n ...initialState(),\n\n addClip(clip) {\n const id = nextId('clip')\n const full: Clip = {\n ...clip,\n id,\n caption: clip.caption ?? defaultCaption(clip.fileName, clip.page),\n zoomBase: clip.zoomBase ?? clip.rect.w,\n }\n set((state) => ({ clips: [...state.clips, full] }))\n const slide = get().slides[get().current]\n if (slide && slide.items.length < AUTO_PLACE_BELOW) get().place(id)\n return id\n },\n\n removeClip(clipId) {\n const { clips, slides } = get()\n const removed = clips.find((clip) => clip.id === clipId)\n if (!removed) return\n const rest = clips.filter((clip) => clip.id !== clipId)\n set({\n clips: rest,\n slides: slides.map((slide) => {\n if (!slide.items.some((item) => item.clipId === clipId)) return slide\n const next = { ...slide, items: slide.items.filter((item) => item.clipId !== clipId) }\n return next.auto ? arranged(next, rest, get()) : next\n }),\n })\n // The PDF engine's copy of the file goes once no clip is drawn from it.\n if (!rest.some((clip) => clip.source === removed.source))\n releasePdfRegionSource(removed.source)\n },\n\n setCaption: (clipId, caption) =>\n set((state) => ({\n clips: state.clips.map((clip) => (clip.id === clipId ? { ...clip, caption } : clip)),\n })),\n\n place: (clipId, at) =>\n updateSlide((slide, clips) => {\n if (!clips.some((clip) => clip.id === clipId)) return slide\n const others = slide.items.filter((item) => item.clipId !== clipId)\n if (!at && others.length < slide.items.length) return slide\n if (others.length >= MAX_ITEMS_PER_SLIDE) return slide\n const aspect = aspectOf(clips, clipId)\n // An auto slide arranges it with the rest. A slide arranged by hand stays so: the clip goes\n // where it was dropped, or in the middle.\n const frame = slide.auto ? fitFrame(aspect) : dropFrame(aspect, at ?? { x: 0.5, y: 0.5 })\n return { ...slide, items: [...others, { clipId, frame }] }\n }),\n\n unplace: (clipId) =>\n updateSlide((slide) =>\n slide.items.some((item) => item.clipId === clipId)\n ? { ...slide, items: slide.items.filter((item) => item.clipId !== clipId) }\n : slide\n ),\n\n setFrame: (clipId, frame) =>\n updateSlide((slide) => ({\n ...slide,\n auto: false,\n items: slide.items.map((item) => (item.clipId === clipId ? { ...item, frame } : item)),\n })),\n\n applyFrame(clipId, command) {\n const slide = get().slides[get().current]\n const item = slide?.items.find((entry) => entry.clipId === clipId)\n if (!item) return\n const aspect = aspectOf(get().clips, clipId)\n const reserve = reserveOf(slide, get())\n const frame =\n command === 'fullWidth'\n ? fullWidthFrame(item.frame, aspect, reserve)\n : command === 'fullHeight'\n ? fullHeightFrame(item.frame, aspect, reserve)\n : fitFrame(aspect, reserve)\n get().setFrame(clipId, frame)\n // Made the size of the stage, it goes on top of the others.\n get().bringToFront(clipId)\n },\n\n bringToFront: (clipId) => restack(clipId, 'front'),\n sendToBack: (clipId) => restack(clipId, 'back'),\n\n panClip: (clipId, dx, dy) =>\n set((state) => {\n const clip = state.clips.find((entry) => entry.id === clipId)\n if (!clip) return state\n const { rect } = clip\n const x = Math.min(Math.max(rect.x + dx, 0), 1 - rect.w)\n const y = Math.min(Math.max(rect.y + dy, 0), 1 - rect.h)\n if (x === rect.x && y === rect.y) return state\n return {\n clips: state.clips.map((entry) =>\n entry === clip ? { ...clip, rect: { ...rect, x, y } } : entry\n ),\n }\n }),\n\n zoomClip: (clipId, factor) =>\n set((state) => {\n const clip = state.clips.find((entry) => entry.id === clipId)\n if (!clip || !(factor > 0)) return state\n const { rect } = clip\n // Its area scales by 1/factor; never larger than the source, nor smaller than a sliver.\n const largest = Math.min(1 / rect.w, 1 / rect.h)\n const smallest = Math.max(MIN_CLIP_AREA / rect.w, MIN_CLIP_AREA / rect.h)\n const scale = Math.min(Math.max(1 / factor, smallest), largest)\n if (scale === 1) return state\n const w = rect.w * scale\n const h = rect.h * scale\n const x = Math.min(Math.max(rect.x + (rect.w - w) / 2, 0), 1 - w)\n const y = Math.min(Math.max(rect.y + (rect.h - h) / 2, 0), 1 - h)\n return {\n clips: state.clips.map((entry) =>\n entry === clip ? { ...clip, rect: { x, y, w, h } } : entry\n ),\n }\n }),\n\n setClipZoom(clipId, percent) {\n const clip = get().clips.find((entry) => entry.id === clipId)\n if (!clip || !(percent > 0)) return\n const width = (clip.zoomBase ?? clip.rect.w) / (percent / 100)\n get().zoomClip(clipId, clip.rect.w / width)\n },\n\n align(clipId, alignment) {\n const slide = get().slides[get().current]\n const item = slide?.items.find((entry) => entry.clipId === clipId)\n if (!slide || !item) return\n const aspect = aspectOf(get().clips, clipId)\n get().setFrame(clipId, alignFrame(item.frame, aspect, alignment, reserveOf(slide, get())))\n },\n\n nudge(clipId, dx, dy) {\n const slide = get().slides[get().current]\n const item = slide?.items.find((entry) => entry.clipId === clipId)\n if (!item) return\n const aspect = aspectOf(get().clips, clipId)\n get().setFrame(clipId, moveFrame(item.frame, aspect, dx, dy, [], true).frame)\n },\n\n // An auto slide makes (or gives back) the caption's room; one arranged by hand keeps its places.\n // A blank slide's title is its title box's text.\n setSlideCaption: (caption, index) =>\n updateSlide(\n (slide) => ({\n ...slide,\n caption,\n boxes: slide.boxes.map((box) => (box.role === 'title' ? withText(box, caption) : box)),\n }),\n index\n ),\n setSlideLayout: (layout, index) =>\n updateSlide((slide) => ({ ...slide, layout, auto: true }), index),\n setSlidePoints: (points, index) => updateSlide((slide) => ({ ...slide, points }), index),\n\n setTheme: (change) =>\n set((state) => {\n const theme = { ...state.theme, ...change }\n const logoMoved = (theme.logo?.corner ?? null) !== (state.theme.logo?.corner ?? null)\n return {\n theme,\n ...(theme.logo?.documentId !== state.theme.logo?.documentId ? { logoImage: null } : {}),\n slides: logoMoved\n ? state.slides.map((slide) =>\n slide.auto ? arranged(slide, state.clips, { ...state, theme }) : slide\n )\n : state.slides,\n }\n }),\n setLogoImage: (logoImage) => set({ logoImage }),\n\n arrange: () => updateSlide((slide) => ({ ...slide, auto: true })),\n\n addSlide: (layout, after) =>\n set((state) => {\n const at = (after ?? state.current) + 1\n const slides = state.slides.slice()\n const before = state.slides[at - 1]\n const slide = emptySlide(layout ?? before?.layout ?? 'clips')\n // The slide it follows keeps its look (an imported deck's background).\n slides.splice(\n at,\n 0,\n before?.background ? { ...slide, background: before.background } : slide\n )\n return { slides, current: at }\n }),\n\n removeSlide: (index) =>\n set((state) => {\n const target = index ?? state.current\n if (state.slides.length <= 1) return { slides: [emptySlide()], current: 0 }\n const slides = state.slides.filter((_, i) => i !== target)\n const current = state.current > target ? state.current - 1 : state.current\n return { slides, current: Math.min(current, slides.length - 1) }\n }),\n\n duplicateSlide: (index) =>\n set((state) => {\n const slide = state.slides[index]\n if (!slide) return state\n const slides = state.slides.slice()\n slides.splice(index + 1, 0, {\n ...slide,\n id: nextId('slide'),\n items: slide.items.map((item) => ({ ...item, frame: { ...item.frame } })),\n boxes: slide.boxes.map((box) => ({ ...box, id: nextBoxId() })),\n })\n return { slides, current: index + 1 }\n }),\n\n moveSlide: (index, to) =>\n set((state) => {\n if (to < 0 || to >= state.slides.length || index === to || !state.slides[index]) {\n return state\n }\n const slides = state.slides.slice()\n const [slide] = slides.splice(index, 1)\n slides.splice(to, 0, slide)\n return { slides, current: to }\n }),\n\n goTo: (index) =>\n set((state) =>\n index < 0 || index >= state.slides.length || index === state.current\n ? state\n : { current: index }\n ),\n\n setBlank: (blank) => set({ blank }),\n // Slides arranged automatically make (or give back) the captions' room.\n setCaptions: (captions) =>\n set((state) => ({\n captions,\n slides: state.slides.map((slide) =>\n slide.auto ? arranged(slide, state.clips, { ...state, captions }) : slide\n ),\n })),\n setLabelColumn: (labelColumn) => set({ labelColumn }),\n setColumnValues: (columnValues) => set({ columnValues }),\n setPresenting: (presenting) => set({ presenting }),\n setDragging: (dragging) => set({ dragging }),\n setTitle: (title) => set({ title }),\n notify: (text, kind) => set({ notice: { text, kind, id: ++sequence } }),\n clearNotice: (id) => set((state) => (state.notice?.id === id ? { notice: null } : state)),\n\n cropClip: (clipId, rect, aspect) =>\n set((state) => {\n const clips = state.clips.map((clip) =>\n clip.id === clipId ? { ...clip, rect, aspect } : clip\n )\n return {\n clips,\n // Its shape changed: slides arranged automatically arrange again around it.\n slides: state.slides.map((slide) =>\n slide.auto && slide.items.some((item) => item.clipId === clipId)\n ? arranged(slide, clips, state)\n : slide\n ),\n }\n }),\n reshapeClip: (clipId, frame, rect, aspect) =>\n set((state) => {\n const clip = state.clips.find((entry) => entry.id === clipId)\n if (!clip) return state\n // Its zoom reads against its width when cut: that scales with the width it now shows.\n const zoomBase = ((clip.zoomBase ?? clip.rect.w) * rect.w) / clip.rect.w\n const clips = state.clips.map((entry) =>\n entry === clip ? { ...clip, rect, aspect, zoomBase } : entry\n )\n return {\n clips,\n slides: state.slides.map((slide, index) => {\n if (index === state.current) {\n return {\n ...slide,\n auto: false,\n items: slide.items.map((item) =>\n item.clipId === clipId ? { ...item, frame } : item\n ),\n }\n }\n return slide.auto && slide.items.some((item) => item.clipId === clipId)\n ? arranged(slide, clips, state)\n : slide\n }),\n }\n }),\n addBox(box, index) {\n const id = nextBoxId()\n updateSlide((slide) => ({ ...slide, boxes: [...slide.boxes, { ...box, id }] }), index)\n return id\n },\n updateBox: (boxId, change) =>\n updateBoxes(boxId, (boxes, at) => {\n const next = boxes.slice()\n next[at] = change(boxes[at])\n return next\n }),\n setBoxText(boxId, text) {\n get().updateBox(boxId, (box) => withText(box, text))\n // A blank slide's title box is its title too (what an outline reads).\n set((state) => ({\n slides: state.slides.map((slide) =>\n slide.boxes.some((box) => box.id === boxId && box.role === 'title')\n ? { ...slide, caption: text.replace(/\\s*\\n\\s*/g, ' ').trim() }\n : slide\n ),\n }))\n },\n removeBox: (boxId) => updateBoxes(boxId, (boxes, at) => boxes.filter((_, i) => i !== at)),\n restackBox: (boxId, to) =>\n updateBoxes(boxId, (boxes, at) => {\n const box = { ...boxes[at], front: to === 'front' }\n const rest = boxes.filter((_, i) => i !== at)\n return to === 'front' ? [...rest, box] : [box, ...rest]\n }),\n setSlideNotes: (notes, index) => updateSlide((slide) => ({ ...slide, notes }), index),\n setSlideBackground: (background, index) =>\n updateSlide((slide) => {\n const { background: _old, ...rest } = slide\n void _old\n return background ? { ...rest, background } : rest\n }, index),\n setSaved: (savedId, title, version = null) => {\n set({ savedId, title, boundTo: savedId, version })\n set({ clean: snapshotOf(get()) })\n },\n bind: (boundTo) => set({ boundTo }),\n adoptClips: (adopted) =>\n set((state) => ({\n clips: [\n ...state.clips,\n ...adopted.filter((clip) => !state.clips.some((entry) => entry.id === clip.id)),\n ],\n })),\n\n load(opened) {\n get().reset()\n const clips: Clip[] = opened.clips.map((clip) => ({ ...clip, id: nextId('clip') }))\n const slides: Slide[] = opened.slides.map((slide) => ({\n id: nextId('slide'),\n caption: slide.caption,\n auto: slide.auto,\n layout: slide.layout ?? 'clips',\n points: slide.points ?? '',\n // Items whose clip could not be opened are left out.\n items: slide.items\n .filter((item) => clips[item.clip])\n .map((item) => ({ clipId: clips[item.clip].id, frame: item.frame })),\n boxes: (slide.boxes ?? []).map((box) => ({ ...box, id: nextBoxId() })),\n ...(slide.background ? { background: slide.background } : {}),\n ...(slide.notes ? { notes: slide.notes } : {}),\n }))\n set({\n title: opened.title,\n savedId: opened.savedId,\n version: opened.version ?? null,\n boundTo: opened.boundTo ?? opened.savedId,\n captions: opened.captions,\n labelColumn: opened.labelColumn ?? null,\n theme: opened.theme ?? DEFAULT_THEME,\n clips,\n slides: slides.length ? slides : [emptySlide()],\n current: 0,\n media: opened.media ?? {},\n })\n set({ clean: opened.savedId ? snapshotOf(get()) : null })\n },\n\n reset() {\n for (const source of new Set(get().clips.map((clip) => clip.source))) {\n releasePdfRegionSource(source)\n }\n set(initialState())\n },\n }\n})\n\n/** The slide on the stage. */\nexport const currentSlide = (state: PresentationState): Slide | undefined =>\n state.slides[state.current]\n\n/** What is saved of a presentation, as text (to compare). */\nfunction snapshotOf(state: PresentationState): string {\n // Embedded images change only with the clips that show them: left out, so comparing stays cheap.\n return JSON.stringify(serializePresentation({ ...state, media: undefined }))\n}\n\n/**\n * The presentation has changes not saved: since it was opened or saved; or, never saved, anything\n * in it at all (a clip, a title, a point).\n */\nexport function hasUnsavedChanges(state: PresentationState): boolean {\n if (state.clean !== null) return snapshotOf(state) !== state.clean\n return (\n state.clips.length > 0 ||\n state.slides.some(\n (slide) =>\n slide.items.length || slide.boxes.length || slide.caption.trim() || slide.points.trim()\n )\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["slide"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A presentation's theme: one look for every slide (background, typeface, accent colour, a logo
|
|
3
|
+
* in the footer). The same values draw the stage (CSS), the saved PDF (canvas) and the PowerPoint
|
|
4
|
+
* export, so they always match.
|
|
5
|
+
*
|
|
6
|
+
* Backgrounds are dark, for contrast with the clips: a deep diagonal gradient with a soft light
|
|
7
|
+
* from the top left (the gloss), optionally a fine texture. A custom colour gets the same
|
|
8
|
+
* treatment. Typefaces are ones PowerPoint has, so an exported deck keeps its type.
|
|
9
|
+
*/
|
|
10
|
+
import type { SlideBackground } from './boxes';
|
|
11
|
+
export type FontId = 'sans' | 'serif' | 'classic';
|
|
12
|
+
export type LogoCorner = 'bl' | 'br';
|
|
13
|
+
export interface ThemeLogo {
|
|
14
|
+
/** An image document of the workspace (a reference; its file is fetched when opened). */
|
|
15
|
+
documentId: string;
|
|
16
|
+
fileName: string;
|
|
17
|
+
corner: LogoCorner;
|
|
18
|
+
}
|
|
19
|
+
export interface Theme {
|
|
20
|
+
/** A background preset's id, or a custom colour (`#rrggbb`). */
|
|
21
|
+
background: string;
|
|
22
|
+
font: FontId;
|
|
23
|
+
/** `#rrggbb`: the rule under titles, bullets. */
|
|
24
|
+
accent: string;
|
|
25
|
+
logo: ThemeLogo | null;
|
|
26
|
+
}
|
|
27
|
+
/** The app's own colours (its `--primary` and `--secondary` tokens), as a background or accent. */
|
|
28
|
+
export declare const BRAND = "brand";
|
|
29
|
+
/** By default a presentation wears the app's brand: its primary as the background, its accent. */
|
|
30
|
+
export declare const DEFAULT_THEME: Theme;
|
|
31
|
+
interface BackgroundSpec {
|
|
32
|
+
/** Top left of the gradient. */
|
|
33
|
+
from: string;
|
|
34
|
+
/** Bottom right. */
|
|
35
|
+
to: string;
|
|
36
|
+
/** The light from the top left (white, this opacity). */
|
|
37
|
+
glow: number;
|
|
38
|
+
texture?: 'linen';
|
|
39
|
+
}
|
|
40
|
+
export declare const BACKGROUNDS: ({
|
|
41
|
+
id: string;
|
|
42
|
+
label: string;
|
|
43
|
+
} & BackgroundSpec)[];
|
|
44
|
+
export declare const FONTS: Record<FontId, {
|
|
45
|
+
label: string;
|
|
46
|
+
css: string;
|
|
47
|
+
pptx: string;
|
|
48
|
+
}>;
|
|
49
|
+
export declare const ACCENTS: {
|
|
50
|
+
label: string;
|
|
51
|
+
color: string;
|
|
52
|
+
}[];
|
|
53
|
+
/** Slide text colours, over the dark background. */
|
|
54
|
+
export declare const TEXT_COLORS: {
|
|
55
|
+
title: string;
|
|
56
|
+
body: string;
|
|
57
|
+
muted: string;
|
|
58
|
+
};
|
|
59
|
+
export declare const isHexColor: (value: string) => boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The app's brand colours, from its `--primary` and `--secondary` tokens (another host's, in that
|
|
62
|
+
* host). The primary stays deep, as a slide background: in a dark mode, where the token is light,
|
|
63
|
+
* its hue is kept at the light theme's depth. Read once.
|
|
64
|
+
*/
|
|
65
|
+
export declare function brandColors(): {
|
|
66
|
+
primary: string;
|
|
67
|
+
secondary: string;
|
|
68
|
+
};
|
|
69
|
+
/** A theme's accent as a colour (`brand`: the app's secondary colour). */
|
|
70
|
+
export declare const accentColor: (accent: string) => string;
|
|
71
|
+
/** The background a theme names: a preset, or a custom colour given the presets' finish. */
|
|
72
|
+
export declare function backgroundSpec(background: string): BackgroundSpec;
|
|
73
|
+
/** The background as CSS (container units: the texture keeps its size on any stage). */
|
|
74
|
+
export declare function backgroundCss(background: string): string;
|
|
75
|
+
/** The background painted on a canvas (the saved PDF's pages, the PowerPoint backgrounds). */
|
|
76
|
+
export declare function paintBackground(context: CanvasRenderingContext2D, width: number, height: number, background: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* A page clip's soft edge: paper white at its very edge (`CLIP_EDGE_SOLID`), fading to nothing by
|
|
79
|
+
* `CLIP_EDGE_FADE` (fractions of the stage width; never more than `CLIP_EDGE_MAX` of the clip), so
|
|
80
|
+
* text cut by the clip fades out instead of being sliced, and the clip has a little margin.
|
|
81
|
+
*/
|
|
82
|
+
export declare const CLIP_EDGE_SOLID = 0.002;
|
|
83
|
+
export declare const CLIP_EDGE_FADE = 0.009;
|
|
84
|
+
export declare const CLIP_EDGE_MAX = 0.08;
|
|
85
|
+
/** The soft edge as CSS (on the stage: container units). */
|
|
86
|
+
export declare function clipEdgeCss(): string;
|
|
87
|
+
/** The soft edge painted over a clip drawn in `box` (the saved PDF, the PowerPoint images). */
|
|
88
|
+
export declare function paintClipEdge(context: CanvasRenderingContext2D, box: {
|
|
89
|
+
x: number;
|
|
90
|
+
y: number;
|
|
91
|
+
width: number;
|
|
92
|
+
height: number;
|
|
93
|
+
}, stageWidth: number): void;
|
|
94
|
+
/** A slide's own background as CSS: its image (from the presentation's media), gradient or colour. */
|
|
95
|
+
export declare function slideBackgroundCss(background: SlideBackground, media: Readonly<Record<string, string>>): string;
|
|
96
|
+
/** A slide's own background painted on a canvas. */
|
|
97
|
+
export declare function paintSlideBackground(context: CanvasRenderingContext2D, width: number, height: number, background: SlideBackground, media: Readonly<Record<string, string>>): Promise<void>;
|
|
98
|
+
/** Whether a slide's background is light (text on it should be dark). */
|
|
99
|
+
export declare function isLightBackground(background: SlideBackground | undefined): boolean;
|
|
100
|
+
/** A theme read from saved data, every field checked (anything wrong falls back to the default). */
|
|
101
|
+
export declare function parseTheme(value: unknown): Theme;
|
|
102
|
+
export {};
|