pptx-react-viewer 3.3.0 → 3.4.0
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/CHANGELOG.md +24 -0
- package/dist/{AiChatPanel-WNQCTQB5.js → AiChatPanel-3Q4STA5E.js} +25 -25
- package/dist/AiChatPanel-3Q4STA5E.js.br +0 -0
- package/dist/AiChatPanel-3Q4STA5E.js.gz +0 -0
- package/dist/{AiChatPanel-BNFDBP4S.mjs → AiChatPanel-NQZBZIRM.mjs} +4 -4
- package/dist/AiChatPanel-NQZBZIRM.mjs.br +0 -0
- package/dist/AiChatPanel-NQZBZIRM.mjs.gz +0 -0
- package/dist/{Area3DChartScene-SAQVRYOH.mjs → Area3DChartScene-7PARQDOZ.mjs} +1 -1
- package/dist/Area3DChartScene-7PARQDOZ.mjs.br +3 -0
- package/dist/Area3DChartScene-7PARQDOZ.mjs.gz +0 -0
- package/dist/{Area3DChartScene-FXBSLIGX.js → Area3DChartScene-THLG74CM.js} +2 -2
- package/dist/Area3DChartScene-THLG74CM.js.br +0 -0
- package/dist/Area3DChartScene-THLG74CM.js.gz +0 -0
- package/dist/{Bar3DChartScene-7HVUTP2E.js → Bar3DChartScene-OLZ2V56I.js} +2 -2
- package/dist/Bar3DChartScene-OLZ2V56I.js.br +2 -0
- package/dist/Bar3DChartScene-OLZ2V56I.js.gz +0 -0
- package/dist/{Bar3DChartScene-LUA6E2K6.mjs → Bar3DChartScene-QUU6RUXM.mjs} +1 -1
- package/dist/Bar3DChartScene-QUU6RUXM.mjs.br +0 -0
- package/dist/Bar3DChartScene-QUU6RUXM.mjs.gz +0 -0
- package/dist/{Line3DChartScene-OVPULUTF.js → Line3DChartScene-2VZS52IB.js} +2 -2
- package/dist/Line3DChartScene-2VZS52IB.js.br +0 -0
- package/dist/Line3DChartScene-2VZS52IB.js.gz +0 -0
- package/dist/{Line3DChartScene-IW4JGH57.mjs → Line3DChartScene-D77ORA4K.mjs} +1 -1
- package/dist/Line3DChartScene-D77ORA4K.mjs.br +3 -0
- package/dist/Line3DChartScene-D77ORA4K.mjs.gz +0 -0
- package/dist/{Model3DScene-5KP6BVCV.js → Model3DScene-3WCALTXO.js} +2 -2
- package/dist/Model3DScene-3WCALTXO.js.br +0 -0
- package/dist/Model3DScene-3WCALTXO.js.gz +0 -0
- package/dist/{Model3DScene-BERTZYCJ.mjs → Model3DScene-ZEGWNILH.mjs} +1 -1
- package/dist/Model3DScene-ZEGWNILH.mjs.br +0 -0
- package/dist/Model3DScene-ZEGWNILH.mjs.gz +0 -0
- package/dist/{PieChart3DScene-3R2ETTGA.js → PieChart3DScene-7C3ACGKN.js} +2 -2
- package/dist/PieChart3DScene-7C3ACGKN.js.br +0 -0
- package/dist/PieChart3DScene-7C3ACGKN.js.gz +0 -0
- package/dist/{PieChart3DScene-O6FFK5L7.mjs → PieChart3DScene-DGD4PZVV.mjs} +1 -1
- package/dist/PieChart3DScene-DGD4PZVV.mjs.br +0 -0
- package/dist/PieChart3DScene-DGD4PZVV.mjs.gz +0 -0
- package/dist/PowerPointViewer-Cl6jBPNw.d.ts.map +1 -1
- package/dist/{SurfaceChart3DScene-OCR26R5D.mjs → SurfaceChart3DScene-QGH3OLJV.mjs} +1 -1
- package/dist/SurfaceChart3DScene-QGH3OLJV.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-QGH3OLJV.mjs.gz +0 -0
- package/dist/{SurfaceChart3DScene-TGFAOLHL.js → SurfaceChart3DScene-SJPQGGGE.js} +2 -2
- package/dist/SurfaceChart3DScene-SJPQGGGE.js.br +0 -0
- package/dist/SurfaceChart3DScene-SJPQGGGE.js.gz +0 -0
- package/dist/{chunk-QKSYKQEL.js → chunk-7E6SM42A.js} +2513 -1626
- package/dist/chunk-7E6SM42A.js.br +0 -0
- package/dist/chunk-7E6SM42A.js.gz +0 -0
- package/dist/{chunk-DM2IZCSD.mjs → chunk-B7WAGQW4.mjs} +2955 -835
- package/dist/chunk-B7WAGQW4.mjs.br +0 -0
- package/dist/chunk-B7WAGQW4.mjs.gz +0 -0
- package/dist/{chunk-2FTJAMFA.mjs → chunk-C4WTQIC6.mjs} +13 -5
- package/dist/chunk-C4WTQIC6.mjs.br +0 -0
- package/dist/chunk-C4WTQIC6.mjs.gz +0 -0
- package/dist/{chunk-FSQCEAMG.js → chunk-KY6JQJXK.js} +17 -9
- package/dist/chunk-KY6JQJXK.js.br +0 -0
- package/dist/chunk-KY6JQJXK.js.gz +0 -0
- package/dist/{chunk-3B5FRKYU.mjs → chunk-L5MRKDRM.mjs} +1397 -510
- package/dist/chunk-L5MRKDRM.mjs.br +0 -0
- package/dist/chunk-L5MRKDRM.mjs.gz +0 -0
- package/dist/{chunk-QEEU4S4Z.mjs → chunk-MSUUPLQ7.mjs} +671 -114
- package/dist/chunk-MSUUPLQ7.mjs.br +0 -0
- package/dist/chunk-MSUUPLQ7.mjs.gz +0 -0
- package/dist/{chunk-K6R2JNCK.js → chunk-PCW2KT7Z.js} +2987 -834
- package/dist/chunk-PCW2KT7Z.js.br +0 -0
- package/dist/chunk-PCW2KT7Z.js.gz +0 -0
- package/dist/{chunk-ITN5NYYM.mjs → chunk-SFMATKNJ.mjs} +6 -19
- package/dist/chunk-SFMATKNJ.mjs.br +0 -0
- package/dist/chunk-SFMATKNJ.mjs.gz +0 -0
- package/dist/{chunk-GR6SJJIT.js → chunk-TJNG5VEK.js} +1080 -518
- package/dist/chunk-TJNG5VEK.js.br +0 -0
- package/dist/chunk-TJNG5VEK.js.gz +0 -0
- package/dist/{chunk-3P7FYHJH.js → chunk-UNIJUD5C.js} +44 -1
- package/dist/chunk-UNIJUD5C.js.br +0 -0
- package/dist/{chunk-3P7FYHJH.js.gz → chunk-UNIJUD5C.js.gz} +0 -0
- package/dist/{chunk-44CQ67GQ.js → chunk-XBTHWXNO.js} +172 -185
- package/dist/chunk-XBTHWXNO.js.br +0 -0
- package/dist/chunk-XBTHWXNO.js.gz +0 -0
- package/dist/{chunk-AMRT3AE4.mjs → chunk-XWUMM2TX.mjs} +44 -1
- package/dist/chunk-XWUMM2TX.mjs.br +0 -0
- package/dist/{chunk-AMRT3AE4.mjs.gz → chunk-XWUMM2TX.mjs.gz} +0 -0
- package/dist/i18n.js +4 -4
- package/dist/i18n.js.br +0 -0
- package/dist/i18n.js.gz +0 -0
- package/dist/i18n.mjs +1 -1
- package/dist/i18n.mjs.br +0 -0
- package/dist/i18n.mjs.gz +0 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +47 -47
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +176 -5
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +79 -79
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +4 -4
- package/dist/internals.mjs.br +0 -0
- package/dist/internals.mjs.gz +0 -0
- package/dist/pptx-viewer.css +1 -1
- package/dist/pptx-viewer.css.br +0 -0
- package/dist/pptx-viewer.css.gz +0 -0
- package/dist/{useViewerBuildingBlocks-X1L8BjsQ.d.ts → useViewerBuildingBlocks-f6oNGKMX.d.ts} +8 -1
- package/dist/useViewerBuildingBlocks-f6oNGKMX.d.ts.map +1 -0
- package/dist/viewer/index.js +27 -27
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +6 -6
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +1 -1
- package/dist/AiChatPanel-BNFDBP4S.mjs.br +0 -0
- package/dist/AiChatPanel-BNFDBP4S.mjs.gz +0 -0
- package/dist/AiChatPanel-WNQCTQB5.js.br +0 -0
- package/dist/AiChatPanel-WNQCTQB5.js.gz +0 -0
- package/dist/Area3DChartScene-FXBSLIGX.js.br +0 -0
- package/dist/Area3DChartScene-FXBSLIGX.js.gz +0 -0
- package/dist/Area3DChartScene-SAQVRYOH.mjs.br +0 -0
- package/dist/Area3DChartScene-SAQVRYOH.mjs.gz +0 -0
- package/dist/Bar3DChartScene-7HVUTP2E.js.br +0 -0
- package/dist/Bar3DChartScene-7HVUTP2E.js.gz +0 -0
- package/dist/Bar3DChartScene-LUA6E2K6.mjs.br +0 -3
- package/dist/Bar3DChartScene-LUA6E2K6.mjs.gz +0 -0
- package/dist/Line3DChartScene-IW4JGH57.mjs.br +0 -0
- package/dist/Line3DChartScene-IW4JGH57.mjs.gz +0 -0
- package/dist/Line3DChartScene-OVPULUTF.js.br +0 -0
- package/dist/Line3DChartScene-OVPULUTF.js.gz +0 -0
- package/dist/Model3DScene-5KP6BVCV.js.br +0 -0
- package/dist/Model3DScene-5KP6BVCV.js.gz +0 -0
- package/dist/Model3DScene-BERTZYCJ.mjs.br +0 -0
- package/dist/Model3DScene-BERTZYCJ.mjs.gz +0 -0
- package/dist/PieChart3DScene-3R2ETTGA.js.br +0 -0
- package/dist/PieChart3DScene-3R2ETTGA.js.gz +0 -0
- package/dist/PieChart3DScene-O6FFK5L7.mjs.br +0 -0
- package/dist/PieChart3DScene-O6FFK5L7.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-OCR26R5D.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-OCR26R5D.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-TGFAOLHL.js.br +0 -0
- package/dist/SurfaceChart3DScene-TGFAOLHL.js.gz +0 -0
- package/dist/chunk-2FTJAMFA.mjs.br +0 -0
- package/dist/chunk-2FTJAMFA.mjs.gz +0 -0
- package/dist/chunk-3B5FRKYU.mjs.br +0 -0
- package/dist/chunk-3B5FRKYU.mjs.gz +0 -0
- package/dist/chunk-3P7FYHJH.js.br +0 -0
- package/dist/chunk-44CQ67GQ.js.br +0 -0
- package/dist/chunk-44CQ67GQ.js.gz +0 -0
- package/dist/chunk-AMRT3AE4.mjs.br +0 -0
- package/dist/chunk-DM2IZCSD.mjs.br +0 -0
- package/dist/chunk-DM2IZCSD.mjs.gz +0 -0
- package/dist/chunk-FSQCEAMG.js.br +0 -0
- package/dist/chunk-FSQCEAMG.js.gz +0 -0
- package/dist/chunk-GR6SJJIT.js.br +0 -0
- package/dist/chunk-GR6SJJIT.js.gz +0 -0
- package/dist/chunk-ITN5NYYM.mjs.br +0 -0
- package/dist/chunk-ITN5NYYM.mjs.gz +0 -0
- package/dist/chunk-K6R2JNCK.js.br +0 -0
- package/dist/chunk-K6R2JNCK.js.gz +0 -0
- package/dist/chunk-QEEU4S4Z.mjs.br +0 -0
- package/dist/chunk-QEEU4S4Z.mjs.gz +0 -0
- package/dist/chunk-QKSYKQEL.js.br +0 -0
- package/dist/chunk-QKSYKQEL.js.gz +0 -0
- package/dist/useViewerBuildingBlocks-X1L8BjsQ.d.ts.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, buildPdfFromImageData, buildNotesPdf, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-
|
|
2
|
-
import { DEFAULT_VIEWER_OPTIONS, TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createPresenceProjector, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, cancelBuildReveal, PresentationAnimationController, scheduleAutoAdvanceChain, playGroup, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, createPresenterShowGuard, attachPresentationVisibilityPause, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, partitionTemplateElements, resolveAuthoredCustomShowId, buildInitialGuides, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, updateElement, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, downloadBlob, resolveImageResolutionScale, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, collectReferencedFontFamilies, resolveGoogleWebfontHref, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, openPptxFile, readBackstageRecentFile, isActionHidden, resolveInlineEditAutoFitHeight, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex,
|
|
3
|
-
import { translationsEn } from './chunk-
|
|
1
|
+
import { cloneHistorySnapshot, MIN_ELEMENT_SIZE, ZOOM_TO_SELECTION_PADDING, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, UNGROUPED_SECTION_ID, DEFAULT_SECTION_GROUP_ID, DEFAULT_TABLE_ROWS, DEFAULT_TABLE_COLUMNS, buildPdfFromImageData, buildNotesPdf, GRID_SIZE, DEFAULT_TEXT_FONT_SIZE } from './chunk-SFMATKNJ.mjs';
|
|
2
|
+
import { DEFAULT_VIEWER_OPTIONS, TOOLBAR_TABS, computeVirtualRange, DEFAULT_VIRTUAL_OVERSCAN, createPresenceProjector, BROADCAST_THROTTLE_MS, createSyncGate, clearLocalAwareness, validateRoomId, createDepartureChannel, resolveTransportForServerUrl, isMixedContentBlocked, CONNECTION_TIMEOUT_MS, registerCollaborationTeardown, sanitizeColor, cloneTemplateElementsBySlideId, cloneSlide, createWheelStepBuffer, createViewerZoomStore, clampZoomScale, mapEditingWheel, cancelBuildReveal, PresentationAnimationController, scheduleAutoAdvanceChain, playGroup, PRESENTATION_HASH, PRESENTATION_NONCE_KEY, PRESENTATION_CHANNEL_NAME, swapPresentationWindows, PRESENTATION_MESSAGE_ORIGIN, clearAudienceContent, buildPresentationAudienceUrl, resolveAudienceScreenPlacement, placeAudienceWindow, storeAudienceContent, isPresentationSessionMessage, endAudienceDisplay, createPresentationKeyBuffer, acceptsPresentationInput, resolveAutoAdvanceDelayMs, hasShowSlideAfter, nextShowSlideIndex, previousShowSlideIndex, createPresenterShowGuard, firstShowSlideIndex, attachPresentationVisibilityPause, presentationEntrySlideIndex, buildMorphTransitionPlan, morphOptionToMode, buildMorphAnimationRules, findInSlides, applyFindReplacements, createCollaborationLivePatcher, publishLiveInlineText, PptxHandler, collectMediaElements, collectImagePaths, applyImagePathPatches, resolveTableCellImageUrls, resolveTableStyleImageUrls, partitionTemplateElements, seedRecentColors, resolveAuthoredCustomShowId, buildInitialGuides, readOnlyRecommendation, compatibilityWarningToasts, EncryptedFileError, resolveAutosaveIntervalMs, shouldWriteAutosaveSnapshot, saveAutosaveSnapshot, autosaveSnapshotMark, updateMasterViewElement, isTemplateElementId, updateElement, hasShapeProperties, hasTextProperties, getInlineEditorSelection, applyStyleToSelectedSegments, setPendingSelectionRestore, applyCaseTransformToSegments, transformTextCase, masterViewElements, replaceMasterViewElements, addSection, renameSection, deleteSection, moveSectionUp, moveSectionDown, moveSlidesToSection, normalizeColorsForCapture, preprocessCssForCapture, slideProgressPercent, slideStatusLabel, EXPORT_ASSEMBLING_PERCENT, EXPORT_DONE_PERCENT, isExportAbortError, recordProgressPercent, downloadBlob, resolveImageResolutionScale, applyThemeToData, THEME_PRESETS, themeColorSchemesEqual, comparePresentation, applyAcceptSlide, applyAcceptAllSlides, collectUsedFonts, describeFontEmbedding, isMobileViewport, resolveAuthoredSlideRange, mayLeaveSlideShow, stopAllPersistentAudio, remapTextToSegments, guidePxToEmu, buildSaveSlides, embeddedFontSaveOptions, resolveSlideSizeSelection, saveDeckWithPassword, shouldProbeAutosaveRecovery, probeAutosaveRecovery, acceptAutosaveRecovery, discardAutosaveRecovery, shouldLoopContinuously, applyRehearsalTimings, copyFormatFromElement, applyFormatToElement, collectReferencedFontFamilies, resolveGoogleWebfontHref, mapSlideShowStartKey, mapEditorKey, isEditorTextInputTarget, createViewerOptionsStore, readSlidesFromYDoc, shouldRoomSlidesReplaceLoad, reconcileSlidesInYDoc, LOCAL_SYNC_ORIGIN, observeYDocSlides, shouldAutoFollowBroadcaster, detectTouchDevice, detectOrientation, deriveViewportBreakpoints, createTouchGestureRecognizer, MAX_ZOOM_SCALE, MIN_ZOOM_SCALE, isKeyboardOpen, scopeLayoutOptionsToSlide, viewerPreferencesFromViewProperties, DEFAULT_VIEWER_PREFERENCES, viewPropertiesPatchFromPreferences, openPptxFile, readBackstageRecentFile, isActionHidden, resolveInlineEditAutoFitHeight, canInteractWithElement, filterInteractableIds, beginShapeAdjustment, buildElementClipboardPayload, savedPresentationFileName, exportDeckJson, groupElements, generateElementId, makeCloneId, ungroupElements, alignElements, distributeElements, bringForward, sendBackward, bringToFront, sendToBack, newTableElement, createDefaultChartElement, readViewportMetrics, computeKeyboardInset, mergeShapes, mapPresentationKey, lastShowSlideIndex, mapPresentationWheel, openPendingPrintWindow, computeColorFilter, filterHiddenSlideIndices, computeSlideIndices, buildPrintDocument, finishPrintWindow, buildPrintHtmlDocument, buildOutlineHtml, buildSlidesHtml, buildNotesHtml, buildHandoutsHtml, createBlankSlide, makeSlideId, buildSlideTemplateSlide, templateSchemeFromTheme, buildThemeColorMap, reResolveSlideColors, computeEntranceAnimationDelay, createPresentationSessionId, resolveTransitionDurationMs, runPresentationAction, safeOpenUrl, toggleStageElementMedia, resolveOleVerbTarget, openUrlInNewTab, createPresenterTimer, createInitialPresentationSnapshot, mergePresentationSnapshot, resetPresenterTimer, presenterElapsed, stepPresenterZoom, togglePresenterTimer, addCommentToList, removeCommentFromList, editCommentInList, toggleCommentResolvedInList, canvasToJpegData, downloadDataUrl, pickSupportedMimeType, WEBM_MIME_CANDIDATES, fpsToFrameIntervalMs, segmentFrameCount, encodeGif, computeGridSpacingPx, resolveShowSlideIndexes, groupSlidesBySection, masterViewPseudoSlide, resolveHistoryDepth, hasCopyableFormat, createBackstagePresentation, buildFieldSubstitutionContext, cloneElementForPaste, computeScrollDelta, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, rerouteConnectorsForMovedElements, applyReroutedConnectors, SvgExporter, replyToCommentInList, deleteTableColumn, rebuildTableStructureInRawXml, insertTableColumn, deleteTableRow, insertTableRow, updateCellTextStyleInRawXml, setCellText, updateCellTextInRawXml, splitCell, updateMergeAttrsInRawXml, mergeCells, isPpactionUrl, parsePpactionUrl, resolvePresentationAction, ACTION_BUTTON_PRESETS, elementActionToPptxAction, isUrlSafe, buildSmartArtPresetData, classifyMediaType, computeSnapToShape, publishLiveGeometry, getDraggedShapeAdjustments, computeMarqueeHitIds, mergeAdditiveSelection, shouldConfirmExternalHyperlink, applyResize, lockResizeAspect, snapBoxToGrid, applyMotionPathPreset } from './chunk-B7WAGQW4.mjs';
|
|
3
|
+
import { translationsEn } from './chunk-XWUMM2TX.mjs';
|
|
4
4
|
import { createContext, useRef, useState, useEffect, useCallback, useMemo, useLayoutEffect, useContext, useImperativeHandle, useSyncExternalStore } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
|
|
@@ -1833,7 +1833,7 @@ function useRehearsalTimings(input) {
|
|
|
1833
1833
|
function handlePresentationActionImpl(action, deps) {
|
|
1834
1834
|
runPresentationAction(
|
|
1835
1835
|
action,
|
|
1836
|
-
{ slideCount: deps.slidesLength },
|
|
1836
|
+
{ slideCount: deps.slidesLength, ...deps.elementId ? { elementId: deps.elementId } : {} },
|
|
1837
1837
|
{
|
|
1838
1838
|
goToSlide: (slideIndex) => {
|
|
1839
1839
|
deps.navigateToSlide(slideIndex);
|
|
@@ -1844,7 +1844,13 @@ function handlePresentationActionImpl(action, deps) {
|
|
|
1844
1844
|
endShow: () => {
|
|
1845
1845
|
deps.onSetMode("edit");
|
|
1846
1846
|
},
|
|
1847
|
-
playSound: deps.onPlayActionSound ? (soundPath) => deps.onPlayActionSound?.(soundPath) : void 0
|
|
1847
|
+
playSound: deps.onPlayActionSound ? (soundPath) => deps.onPlayActionSound?.(soundPath) : void 0,
|
|
1848
|
+
lastViewed: deps.onLastViewed,
|
|
1849
|
+
customShow: deps.onCustomShow,
|
|
1850
|
+
openFile: deps.onOpenFile,
|
|
1851
|
+
openPresentation: deps.onOpenPresentation,
|
|
1852
|
+
playMedia: deps.onPlayMedia,
|
|
1853
|
+
oleVerb: deps.onOleVerb
|
|
1848
1854
|
}
|
|
1849
1855
|
);
|
|
1850
1856
|
}
|
|
@@ -1852,7 +1858,7 @@ function handlePresentationActionImpl(action, deps) {
|
|
|
1852
1858
|
// src/viewer/hooks/presentation-mode/slide-transition.ts
|
|
1853
1859
|
function executeSlideTransition(nextSlideIndex, deps) {
|
|
1854
1860
|
const incomingSlide = deps.slides[nextSlideIndex];
|
|
1855
|
-
const transition = incomingSlide?.transition;
|
|
1861
|
+
const transition = deps.reverse ? deps.slides[deps.currentSlideIndex]?.transition : incomingSlide?.transition;
|
|
1856
1862
|
const durationMs = deps.playTransition ? resolveTransitionDurationMs(transition) : 0;
|
|
1857
1863
|
deps.clearPresentationTimers();
|
|
1858
1864
|
deps.setPresentationSlideIndex(nextSlideIndex);
|
|
@@ -1906,7 +1912,13 @@ function useSlideNavigation(input) {
|
|
|
1906
1912
|
presentationTimersRef,
|
|
1907
1913
|
rehearsing,
|
|
1908
1914
|
recordCurrentSlideTime,
|
|
1909
|
-
setShowRehearsalSummary
|
|
1915
|
+
setShowRehearsalSummary,
|
|
1916
|
+
onLastViewed,
|
|
1917
|
+
onCustomShow,
|
|
1918
|
+
onOpenFile,
|
|
1919
|
+
onOpenPresentation,
|
|
1920
|
+
onPlayMedia,
|
|
1921
|
+
onOleVerb
|
|
1910
1922
|
} = input;
|
|
1911
1923
|
const movePresentationSlideRef = useRef(() => {
|
|
1912
1924
|
});
|
|
@@ -1975,8 +1987,11 @@ function useSlideNavigation(input) {
|
|
|
1975
1987
|
scheduleAutoAdvanceForSlide: rehearsing ? void 0 : scheduleAutoAdvanceForSlide,
|
|
1976
1988
|
presentationTimersRef,
|
|
1977
1989
|
setTransitionOverlay,
|
|
1978
|
-
// PowerPoint plays a slide's transition only when advancing into it
|
|
1979
|
-
|
|
1990
|
+
// PowerPoint plays a slide's transition only when advancing into it,
|
|
1991
|
+
// and replays the LEAVING slide's transition in reverse when stepping
|
|
1992
|
+
// back (a morph glides its shapes back to where they came from).
|
|
1993
|
+
playTransition: true,
|
|
1994
|
+
reverse: direction === -1,
|
|
1980
1995
|
// Stepping back onto a slide shows it with its builds already played.
|
|
1981
1996
|
seedCompleted: direction === -1
|
|
1982
1997
|
});
|
|
@@ -2052,16 +2067,35 @@ function useSlideNavigation(input) {
|
|
|
2052
2067
|
]
|
|
2053
2068
|
);
|
|
2054
2069
|
const handlePresentationAction = useCallback(
|
|
2055
|
-
(action) => {
|
|
2070
|
+
(action, elementId) => {
|
|
2056
2071
|
handlePresentationActionImpl(action, {
|
|
2072
|
+
elementId,
|
|
2057
2073
|
movePresentationSlide,
|
|
2058
2074
|
navigateToSlide,
|
|
2059
2075
|
onPlayActionSound,
|
|
2060
2076
|
onSetMode,
|
|
2061
|
-
slidesLength: slides.length
|
|
2077
|
+
slidesLength: slides.length,
|
|
2078
|
+
onLastViewed,
|
|
2079
|
+
onCustomShow,
|
|
2080
|
+
onOpenFile,
|
|
2081
|
+
onOpenPresentation,
|
|
2082
|
+
onPlayMedia,
|
|
2083
|
+
onOleVerb
|
|
2062
2084
|
});
|
|
2063
2085
|
},
|
|
2064
|
-
[
|
|
2086
|
+
[
|
|
2087
|
+
movePresentationSlide,
|
|
2088
|
+
navigateToSlide,
|
|
2089
|
+
onPlayActionSound,
|
|
2090
|
+
onSetMode,
|
|
2091
|
+
slides.length,
|
|
2092
|
+
onLastViewed,
|
|
2093
|
+
onCustomShow,
|
|
2094
|
+
onOpenFile,
|
|
2095
|
+
onOpenPresentation,
|
|
2096
|
+
onPlayMedia,
|
|
2097
|
+
onOleVerb
|
|
2098
|
+
]
|
|
2065
2099
|
);
|
|
2066
2100
|
return {
|
|
2067
2101
|
movePresentationSlide,
|
|
@@ -2099,6 +2133,136 @@ function useZoomNavigation(input) {
|
|
|
2099
2133
|
clearZoomReturn
|
|
2100
2134
|
};
|
|
2101
2135
|
}
|
|
2136
|
+
function createCustomShowRunner(deps) {
|
|
2137
|
+
let origin = null;
|
|
2138
|
+
return {
|
|
2139
|
+
runCustomShow(customShowId, returnAfter) {
|
|
2140
|
+
const target = deps.getCustomShows().find((show) => show.id === customShowId);
|
|
2141
|
+
if (!target) {
|
|
2142
|
+
return;
|
|
2143
|
+
}
|
|
2144
|
+
origin = returnAfter ? { showId: deps.getActiveCustomShowId(), slideIndex: deps.getPresentationSlideIndex() } : null;
|
|
2145
|
+
const first = firstShowSlideIndex(resolveShowSlideIndexes(deps.getSlides(), target));
|
|
2146
|
+
deps.setActiveCustomShowId(customShowId);
|
|
2147
|
+
if (first !== void 0) {
|
|
2148
|
+
deps.navigateToSlide(first);
|
|
2149
|
+
}
|
|
2150
|
+
},
|
|
2151
|
+
tryReturnFromCustomShow() {
|
|
2152
|
+
if (!origin) {
|
|
2153
|
+
return false;
|
|
2154
|
+
}
|
|
2155
|
+
const { showId, slideIndex } = origin;
|
|
2156
|
+
origin = null;
|
|
2157
|
+
deps.setActiveCustomShowId(showId);
|
|
2158
|
+
deps.navigateToSlide(slideIndex);
|
|
2159
|
+
return true;
|
|
2160
|
+
}
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
function useCustomShowRunner(deps) {
|
|
2164
|
+
const depsRef = useRef(deps);
|
|
2165
|
+
depsRef.current = deps;
|
|
2166
|
+
const runnerRef = useRef(null);
|
|
2167
|
+
runnerRef.current ??= createCustomShowRunner({
|
|
2168
|
+
getSlides: () => depsRef.current.getSlides(),
|
|
2169
|
+
getCustomShows: () => depsRef.current.getCustomShows(),
|
|
2170
|
+
getActiveCustomShowId: () => depsRef.current.getActiveCustomShowId(),
|
|
2171
|
+
setActiveCustomShowId: (id) => depsRef.current.setActiveCustomShowId(id),
|
|
2172
|
+
navigateToSlide: (index) => depsRef.current.navigateToSlide(index),
|
|
2173
|
+
getPresentationSlideIndex: () => depsRef.current.getPresentationSlideIndex()
|
|
2174
|
+
});
|
|
2175
|
+
return runnerRef.current;
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
// src/viewer/hooks/presentation-mode/usePresentationActionExtensions.ts
|
|
2179
|
+
function usePresentationActionExtensions(input) {
|
|
2180
|
+
const {
|
|
2181
|
+
slides,
|
|
2182
|
+
customShows,
|
|
2183
|
+
activeCustomShowId,
|
|
2184
|
+
onSetActiveCustomShowId,
|
|
2185
|
+
presentationSlideIndex,
|
|
2186
|
+
containerRef,
|
|
2187
|
+
endWithBlackSlide,
|
|
2188
|
+
onSetMode,
|
|
2189
|
+
setEndOfShowVisible
|
|
2190
|
+
} = input;
|
|
2191
|
+
const navigateToSlideRef = useRef(null);
|
|
2192
|
+
const navigateToSlideViaRef = useCallback((index) => {
|
|
2193
|
+
navigateToSlideRef.current?.(index);
|
|
2194
|
+
}, []);
|
|
2195
|
+
const customShowRunner = useCustomShowRunner({
|
|
2196
|
+
getSlides: () => slides,
|
|
2197
|
+
getCustomShows: () => customShows,
|
|
2198
|
+
getActiveCustomShowId: () => activeCustomShowId,
|
|
2199
|
+
setActiveCustomShowId: (id) => onSetActiveCustomShowId?.(id),
|
|
2200
|
+
navigateToSlide: navigateToSlideViaRef,
|
|
2201
|
+
getPresentationSlideIndex: () => presentationSlideIndex
|
|
2202
|
+
});
|
|
2203
|
+
const previousSlideRef = useRef(presentationSlideIndex);
|
|
2204
|
+
const lastViewedSlideRef = useRef(null);
|
|
2205
|
+
useEffect(() => {
|
|
2206
|
+
lastViewedSlideRef.current = previousSlideRef.current;
|
|
2207
|
+
previousSlideRef.current = presentationSlideIndex;
|
|
2208
|
+
}, [presentationSlideIndex]);
|
|
2209
|
+
const onCustomShow = useCallback(
|
|
2210
|
+
(customShowId, returnAfter) => {
|
|
2211
|
+
customShowRunner.runCustomShow(customShowId, returnAfter);
|
|
2212
|
+
},
|
|
2213
|
+
[customShowRunner]
|
|
2214
|
+
);
|
|
2215
|
+
const onLastViewed = useCallback(() => {
|
|
2216
|
+
const previous = lastViewedSlideRef.current;
|
|
2217
|
+
if (previous !== null) {
|
|
2218
|
+
navigateToSlideViaRef(previous);
|
|
2219
|
+
}
|
|
2220
|
+
}, [navigateToSlideViaRef]);
|
|
2221
|
+
const onOpenFile = useCallback((target) => {
|
|
2222
|
+
safeOpenUrl(target);
|
|
2223
|
+
}, []);
|
|
2224
|
+
const onOpenPresentation = useCallback((target) => {
|
|
2225
|
+
safeOpenUrl(target);
|
|
2226
|
+
}, []);
|
|
2227
|
+
const onPlayMedia = useCallback(
|
|
2228
|
+
(elementId) => {
|
|
2229
|
+
toggleStageElementMedia(containerRef.current, elementId);
|
|
2230
|
+
},
|
|
2231
|
+
[containerRef]
|
|
2232
|
+
);
|
|
2233
|
+
const onOleVerb = useCallback(
|
|
2234
|
+
(verb, elementId) => {
|
|
2235
|
+
const target = resolveOleVerbTarget(slides[presentationSlideIndex], elementId, verb);
|
|
2236
|
+
if (target) {
|
|
2237
|
+
openUrlInNewTab(target.url);
|
|
2238
|
+
}
|
|
2239
|
+
},
|
|
2240
|
+
[slides, presentationSlideIndex]
|
|
2241
|
+
);
|
|
2242
|
+
const handleAdvancePastLastSlide = useCallback(() => {
|
|
2243
|
+
if (customShowRunner.tryReturnFromCustomShow()) {
|
|
2244
|
+
return;
|
|
2245
|
+
}
|
|
2246
|
+
if (endWithBlackSlide) {
|
|
2247
|
+
setEndOfShowVisible(true);
|
|
2248
|
+
} else {
|
|
2249
|
+
onSetMode("edit");
|
|
2250
|
+
}
|
|
2251
|
+
}, [customShowRunner, endWithBlackSlide, onSetMode, setEndOfShowVisible]);
|
|
2252
|
+
const bindNavigateToSlide = useCallback((navigateToSlide) => {
|
|
2253
|
+
navigateToSlideRef.current = navigateToSlide;
|
|
2254
|
+
}, []);
|
|
2255
|
+
return {
|
|
2256
|
+
onLastViewed,
|
|
2257
|
+
onCustomShow,
|
|
2258
|
+
onOpenFile,
|
|
2259
|
+
onOpenPresentation,
|
|
2260
|
+
onPlayMedia,
|
|
2261
|
+
onOleVerb,
|
|
2262
|
+
handleAdvancePastLastSlide,
|
|
2263
|
+
bindNavigateToSlide
|
|
2264
|
+
};
|
|
2265
|
+
}
|
|
2102
2266
|
function usePresenterConsole(slideIndex, active) {
|
|
2103
2267
|
const timerRef = useRef(createPresenterTimer());
|
|
2104
2268
|
const [snapshot, setSnapshot] = useState(() => createInitialPresentationSnapshot(slideIndex));
|
|
@@ -2155,6 +2319,7 @@ function usePresentationMode(input) {
|
|
|
2155
2319
|
const {
|
|
2156
2320
|
mode,
|
|
2157
2321
|
slides,
|
|
2322
|
+
templateElementsBySlideId,
|
|
2158
2323
|
visibleSlideIndexes,
|
|
2159
2324
|
activeSlideIndex,
|
|
2160
2325
|
containerRef,
|
|
@@ -2171,7 +2336,10 @@ function usePresentationMode(input) {
|
|
|
2171
2336
|
loopContinuously,
|
|
2172
2337
|
showWithAnimation,
|
|
2173
2338
|
useTimings,
|
|
2174
|
-
endWithBlackSlide = true
|
|
2339
|
+
endWithBlackSlide = true,
|
|
2340
|
+
customShows = [],
|
|
2341
|
+
activeCustomShowId = null,
|
|
2342
|
+
onSetActiveCustomShowId
|
|
2175
2343
|
} = input;
|
|
2176
2344
|
const [presentationSlideIndex, setPresentationSlideIndex] = useState(0);
|
|
2177
2345
|
const [presentationSlideVisible, setPresentationSlideVisible] = useState(true);
|
|
@@ -2226,13 +2394,17 @@ function usePresentationMode(input) {
|
|
|
2226
2394
|
setPresenterMode(false);
|
|
2227
2395
|
}
|
|
2228
2396
|
}, [mode]);
|
|
2229
|
-
const
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2397
|
+
const actionExtensions = usePresentationActionExtensions({
|
|
2398
|
+
slides,
|
|
2399
|
+
customShows,
|
|
2400
|
+
activeCustomShowId,
|
|
2401
|
+
onSetActiveCustomShowId,
|
|
2402
|
+
presentationSlideIndex,
|
|
2403
|
+
containerRef,
|
|
2404
|
+
endWithBlackSlide,
|
|
2405
|
+
onSetMode,
|
|
2406
|
+
setEndOfShowVisible
|
|
2407
|
+
});
|
|
2236
2408
|
const {
|
|
2237
2409
|
movePresentationSlide: moveNavigationSlide,
|
|
2238
2410
|
navigateToSlide,
|
|
@@ -2250,7 +2422,7 @@ function usePresentationMode(input) {
|
|
|
2250
2422
|
onPlayActionSound,
|
|
2251
2423
|
loopContinuously,
|
|
2252
2424
|
useTimings,
|
|
2253
|
-
onAdvancePastLastSlide: handleAdvancePastLastSlide,
|
|
2425
|
+
onAdvancePastLastSlide: actionExtensions.handleAdvancePastLastSlide,
|
|
2254
2426
|
playNextAnimationGroup,
|
|
2255
2427
|
clearPresentationTimers,
|
|
2256
2428
|
seedSlideAnimations,
|
|
@@ -2258,8 +2430,15 @@ function usePresentationMode(input) {
|
|
|
2258
2430
|
presentationTimersRef,
|
|
2259
2431
|
rehearsing,
|
|
2260
2432
|
recordCurrentSlideTime,
|
|
2261
|
-
setShowRehearsalSummary
|
|
2433
|
+
setShowRehearsalSummary,
|
|
2434
|
+
onLastViewed: actionExtensions.onLastViewed,
|
|
2435
|
+
onCustomShow: actionExtensions.onCustomShow,
|
|
2436
|
+
onOpenFile: actionExtensions.onOpenFile,
|
|
2437
|
+
onOpenPresentation: actionExtensions.onOpenPresentation,
|
|
2438
|
+
onPlayMedia: actionExtensions.onPlayMedia,
|
|
2439
|
+
onOleVerb: actionExtensions.onOleVerb
|
|
2262
2440
|
});
|
|
2441
|
+
actionExtensions.bindNavigateToSlide(navigateToSlide);
|
|
2263
2442
|
const movePresentationSlide = useCallback(
|
|
2264
2443
|
(direction, trigger = "explicit") => {
|
|
2265
2444
|
if (!acceptsPresentationInput()) {
|
|
@@ -2330,6 +2509,13 @@ function usePresentationMode(input) {
|
|
|
2330
2509
|
}
|
|
2331
2510
|
onSetMode("present");
|
|
2332
2511
|
}, [containerRef, onSetMode, setRehearsing]);
|
|
2512
|
+
const enterPresentModeFromBeginning = useCallback(() => {
|
|
2513
|
+
const first = firstShowSlideIndex(visibleSlideIndexes);
|
|
2514
|
+
if (first !== void 0) {
|
|
2515
|
+
onSetActiveSlideIndex(first);
|
|
2516
|
+
}
|
|
2517
|
+
enterPresentMode();
|
|
2518
|
+
}, [visibleSlideIndexes, onSetActiveSlideIndex, enterPresentMode]);
|
|
2333
2519
|
const enterPresenterView = useCallback(() => {
|
|
2334
2520
|
setPresenterMode(true);
|
|
2335
2521
|
setRehearsing(false);
|
|
@@ -2392,6 +2578,10 @@ function usePresentationMode(input) {
|
|
|
2392
2578
|
scheduleAutoAdvanceRef.current = scheduleAutoAdvanceForSlide;
|
|
2393
2579
|
const activeSlideIndexRef = useRef(activeSlideIndex);
|
|
2394
2580
|
activeSlideIndexRef.current = activeSlideIndex;
|
|
2581
|
+
const visibleSlideIndexesRef = useRef(visibleSlideIndexes);
|
|
2582
|
+
visibleSlideIndexesRef.current = visibleSlideIndexes;
|
|
2583
|
+
const onSetActiveSlideIndexRef = useRef(onSetActiveSlideIndex);
|
|
2584
|
+
onSetActiveSlideIndexRef.current = onSetActiveSlideIndex;
|
|
2395
2585
|
const presentationSlideIndexRef = useRef(presentationSlideIndex);
|
|
2396
2586
|
presentationSlideIndexRef.current = presentationSlideIndex;
|
|
2397
2587
|
const clearPresentationTimersRef = useRef(clearPresentationTimers);
|
|
@@ -2408,8 +2598,14 @@ function usePresentationMode(input) {
|
|
|
2408
2598
|
}, [mode, containerRef]);
|
|
2409
2599
|
useLayoutEffect(() => {
|
|
2410
2600
|
if (mode === "present") {
|
|
2411
|
-
const idx =
|
|
2601
|
+
const idx = presentationEntrySlideIndex(
|
|
2602
|
+
activeSlideIndexRef.current,
|
|
2603
|
+
visibleSlideIndexesRef.current
|
|
2604
|
+
);
|
|
2412
2605
|
setPresentationSlideIndex(idx);
|
|
2606
|
+
if (idx !== activeSlideIndexRef.current) {
|
|
2607
|
+
onSetActiveSlideIndexRef.current(idx);
|
|
2608
|
+
}
|
|
2413
2609
|
runEntranceAnimationsRef.current(idx);
|
|
2414
2610
|
scheduleAutoAdvanceRef.current(idx);
|
|
2415
2611
|
} else {
|
|
@@ -2480,13 +2676,18 @@ function usePresentationMode(input) {
|
|
|
2480
2676
|
if (!transitionOverlay || transitionOverlay.transition.type !== "morph") {
|
|
2481
2677
|
return void 0;
|
|
2482
2678
|
}
|
|
2679
|
+
const incoming = slides[transitionOverlay.incomingSlideIndex];
|
|
2483
2680
|
return buildMorphTransitionPlan(
|
|
2484
2681
|
slides[transitionOverlay.outgoingSlideIndex],
|
|
2485
|
-
|
|
2682
|
+
incoming,
|
|
2486
2683
|
transitionOverlay.durationMs,
|
|
2487
|
-
morphOptionToMode(transitionOverlay.transition.morphOption)
|
|
2684
|
+
morphOptionToMode(transitionOverlay.transition.morphOption),
|
|
2685
|
+
// `PresentationStage` stacks the incoming slide's elements above its
|
|
2686
|
+
// template shapes (`zIndex = templateElements.length + index`), so a
|
|
2687
|
+
// z-index journey has to start counting where the stage does.
|
|
2688
|
+
{ zIndexBase: incoming ? templateElementsBySlideId?.[incoming.id]?.length ?? 0 : 0 }
|
|
2488
2689
|
);
|
|
2489
|
-
}, [transitionOverlay, slides]);
|
|
2690
|
+
}, [transitionOverlay, slides, templateElementsBySlideId]);
|
|
2490
2691
|
const morphedElementStates = useMemo(() => {
|
|
2491
2692
|
if (!morphPlan || morphPlan.incomingAnimations.size === 0) {
|
|
2492
2693
|
return presentationElementStates;
|
|
@@ -2535,6 +2736,7 @@ ${imageRules}`;
|
|
|
2535
2736
|
handleHoverStart,
|
|
2536
2737
|
handleHoverEnd,
|
|
2537
2738
|
enterPresentMode,
|
|
2739
|
+
enterPresentModeFromBeginning,
|
|
2538
2740
|
presenterMode,
|
|
2539
2741
|
enterPresenterView,
|
|
2540
2742
|
togglePresenterView,
|
|
@@ -2926,6 +3128,38 @@ function useModalDismissDrag(onClose, threshold = 120) {
|
|
|
2926
3128
|
handlers: { onPointerDown, onPointerMove, onPointerUp, onPointerCancel: onPointerUp }
|
|
2927
3129
|
};
|
|
2928
3130
|
}
|
|
3131
|
+
function withoutKey(map, key) {
|
|
3132
|
+
if (!(key in map)) {
|
|
3133
|
+
return map;
|
|
3134
|
+
}
|
|
3135
|
+
const next = { ...map };
|
|
3136
|
+
delete next[key];
|
|
3137
|
+
return next;
|
|
3138
|
+
}
|
|
3139
|
+
function useCommentMentionDrafts() {
|
|
3140
|
+
const [commentDraftMentionsBySlideId, setCommentDraftMentionsBySlideId] = useState({});
|
|
3141
|
+
const [replyDraftMentionsByCommentId, setReplyDraftMentionsByCommentId] = useState({});
|
|
3142
|
+
const setCommentDraftMentions = useCallback((slideId, mentions) => {
|
|
3143
|
+
setCommentDraftMentionsBySlideId((prev) => ({ ...prev, [slideId]: mentions }));
|
|
3144
|
+
}, []);
|
|
3145
|
+
const setReplyDraftMentions = useCallback((commentId, mentions) => {
|
|
3146
|
+
setReplyDraftMentionsByCommentId((prev) => ({ ...prev, [commentId]: mentions }));
|
|
3147
|
+
}, []);
|
|
3148
|
+
const clearCommentDraftMentions = useCallback((slideId) => {
|
|
3149
|
+
setCommentDraftMentionsBySlideId((prev) => withoutKey(prev, slideId));
|
|
3150
|
+
}, []);
|
|
3151
|
+
const clearReplyDraftMentions = useCallback((commentId) => {
|
|
3152
|
+
setReplyDraftMentionsByCommentId((prev) => withoutKey(prev, commentId));
|
|
3153
|
+
}, []);
|
|
3154
|
+
return {
|
|
3155
|
+
commentDraftMentionsBySlideId,
|
|
3156
|
+
replyDraftMentionsByCommentId,
|
|
3157
|
+
setCommentDraftMentions,
|
|
3158
|
+
setReplyDraftMentions,
|
|
3159
|
+
clearCommentDraftMentions,
|
|
3160
|
+
clearReplyDraftMentions
|
|
3161
|
+
};
|
|
3162
|
+
}
|
|
2929
3163
|
|
|
2930
3164
|
// src/viewer/hooks/useComments-helpers.ts
|
|
2931
3165
|
function replaceCommentsOnSlide(slides, slideIndex, next) {
|
|
@@ -2933,7 +3167,7 @@ function replaceCommentsOnSlide(slides, slideIndex, next) {
|
|
|
2933
3167
|
(entry, index) => index === slideIndex ? { ...entry, comments: next } : entry
|
|
2934
3168
|
);
|
|
2935
3169
|
}
|
|
2936
|
-
function addCommentToSlide(slides, slideIndex, text, authorName, elementId) {
|
|
3170
|
+
function addCommentToSlide(slides, slideIndex, text, authorName, elementId, mentions) {
|
|
2937
3171
|
const slide = slides[slideIndex];
|
|
2938
3172
|
if (!slide) {
|
|
2939
3173
|
return { slides, didAdd: false };
|
|
@@ -2949,7 +3183,10 @@ function addCommentToSlide(slides, slideIndex, text, authorName, elementId) {
|
|
|
2949
3183
|
if (!next) {
|
|
2950
3184
|
return { slides, didAdd: false };
|
|
2951
3185
|
}
|
|
2952
|
-
|
|
3186
|
+
const withMentions = mentions && mentions.length > 0 ? next.map(
|
|
3187
|
+
(comment, index) => index === next.length - 1 ? { ...comment, mentions } : comment
|
|
3188
|
+
) : next;
|
|
3189
|
+
return { slides: replaceCommentsOnSlide(slides, slideIndex, withMentions), didAdd: true };
|
|
2953
3190
|
}
|
|
2954
3191
|
function removeCommentFromSlide(slides, slideIndex, commentId) {
|
|
2955
3192
|
const slide = slides[slideIndex];
|
|
@@ -2984,7 +3221,7 @@ function toggleResolvedInSlide(slides, slideIndex, commentId) {
|
|
|
2984
3221
|
}
|
|
2985
3222
|
return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didUpdate: true };
|
|
2986
3223
|
}
|
|
2987
|
-
function addReplyToSlide(slides, slideIndex, parentId, text, authorName) {
|
|
3224
|
+
function addReplyToSlide(slides, slideIndex, parentId, text, authorName, mentions) {
|
|
2988
3225
|
const slide = slides[slideIndex];
|
|
2989
3226
|
if (!slide) {
|
|
2990
3227
|
return { slides, didAdd: false };
|
|
@@ -2993,7 +3230,15 @@ function addReplyToSlide(slides, slideIndex, parentId, text, authorName) {
|
|
|
2993
3230
|
if (!next) {
|
|
2994
3231
|
return { slides, didAdd: false };
|
|
2995
3232
|
}
|
|
2996
|
-
|
|
3233
|
+
const withMentions = mentions && mentions.length > 0 ? next.map(
|
|
3234
|
+
(comment) => comment.id === parentId && comment.replies && comment.replies.length > 0 ? {
|
|
3235
|
+
...comment,
|
|
3236
|
+
replies: comment.replies.map(
|
|
3237
|
+
(reply, index) => index === comment.replies.length - 1 ? { ...reply, mentions } : reply
|
|
3238
|
+
)
|
|
3239
|
+
} : comment
|
|
3240
|
+
) : next;
|
|
3241
|
+
return { slides: replaceCommentsOnSlide(slides, slideIndex, withMentions), didAdd: true };
|
|
2997
3242
|
}
|
|
2998
3243
|
function pruneSlideDrafts(drafts, slideIds) {
|
|
2999
3244
|
const next = {};
|
|
@@ -3008,6 +3253,95 @@ function pruneSlideDrafts(drafts, slideIds) {
|
|
|
3008
3253
|
return changed ? next : null;
|
|
3009
3254
|
}
|
|
3010
3255
|
|
|
3256
|
+
// src/viewer/hooks/useCommentReplyHandlers.ts
|
|
3257
|
+
function useCommentReplyHandlers(input) {
|
|
3258
|
+
const {
|
|
3259
|
+
slides,
|
|
3260
|
+
canEdit,
|
|
3261
|
+
userName,
|
|
3262
|
+
onUpdateSlides,
|
|
3263
|
+
onMarkDirty,
|
|
3264
|
+
replyDraftMentionsByCommentId,
|
|
3265
|
+
setReplyDraftMentions,
|
|
3266
|
+
clearReplyDraftMentions
|
|
3267
|
+
} = input;
|
|
3268
|
+
const [replyDraftByCommentId, setReplyDraftByCommentId] = useState({});
|
|
3269
|
+
const [replyingToCommentId, setReplyingToCommentId] = useState(null);
|
|
3270
|
+
const handleStartReply = useCallback((_slideIndex, commentId) => {
|
|
3271
|
+
setReplyingToCommentId(commentId);
|
|
3272
|
+
setReplyDraftByCommentId((prev) => ({ ...prev, [commentId]: "" }));
|
|
3273
|
+
}, []);
|
|
3274
|
+
const handleCancelReply = useCallback(() => {
|
|
3275
|
+
setReplyingToCommentId(null);
|
|
3276
|
+
}, []);
|
|
3277
|
+
const handleReplyDraftChange = useCallback(
|
|
3278
|
+
(commentId, draft, mentions) => {
|
|
3279
|
+
setReplyDraftByCommentId((prev) => ({ ...prev, [commentId]: draft }));
|
|
3280
|
+
if (mentions) {
|
|
3281
|
+
setReplyDraftMentions(commentId, mentions);
|
|
3282
|
+
}
|
|
3283
|
+
},
|
|
3284
|
+
[setReplyDraftMentions]
|
|
3285
|
+
);
|
|
3286
|
+
const handleSubmitReply = useCallback(
|
|
3287
|
+
(slideIndex, commentId) => {
|
|
3288
|
+
if (!canEdit) {
|
|
3289
|
+
return;
|
|
3290
|
+
}
|
|
3291
|
+
const slide = slides[slideIndex];
|
|
3292
|
+
if (!slide) {
|
|
3293
|
+
return;
|
|
3294
|
+
}
|
|
3295
|
+
const replyText = String(replyDraftByCommentId[commentId] || "").trim();
|
|
3296
|
+
if (replyText.length === 0) {
|
|
3297
|
+
return;
|
|
3298
|
+
}
|
|
3299
|
+
let didAdd = false;
|
|
3300
|
+
onUpdateSlides((prev) => {
|
|
3301
|
+
const result = addReplyToSlide(
|
|
3302
|
+
prev,
|
|
3303
|
+
slideIndex,
|
|
3304
|
+
commentId,
|
|
3305
|
+
replyText,
|
|
3306
|
+
userName,
|
|
3307
|
+
replyDraftMentionsByCommentId[commentId]
|
|
3308
|
+
);
|
|
3309
|
+
didAdd = result.didAdd;
|
|
3310
|
+
return result.slides;
|
|
3311
|
+
});
|
|
3312
|
+
if (!didAdd) {
|
|
3313
|
+
return;
|
|
3314
|
+
}
|
|
3315
|
+
setReplyingToCommentId(null);
|
|
3316
|
+
setReplyDraftByCommentId((prev) => {
|
|
3317
|
+
const next = { ...prev };
|
|
3318
|
+
delete next[commentId];
|
|
3319
|
+
return next;
|
|
3320
|
+
});
|
|
3321
|
+
clearReplyDraftMentions(commentId);
|
|
3322
|
+
onMarkDirty();
|
|
3323
|
+
},
|
|
3324
|
+
[
|
|
3325
|
+
canEdit,
|
|
3326
|
+
onMarkDirty,
|
|
3327
|
+
onUpdateSlides,
|
|
3328
|
+
replyDraftByCommentId,
|
|
3329
|
+
replyDraftMentionsByCommentId,
|
|
3330
|
+
clearReplyDraftMentions,
|
|
3331
|
+
slides,
|
|
3332
|
+
userName
|
|
3333
|
+
]
|
|
3334
|
+
);
|
|
3335
|
+
return {
|
|
3336
|
+
replyingToCommentId,
|
|
3337
|
+
replyDraftByCommentId,
|
|
3338
|
+
handleStartReply,
|
|
3339
|
+
handleCancelReply,
|
|
3340
|
+
handleReplyDraftChange,
|
|
3341
|
+
handleSubmitReply
|
|
3342
|
+
};
|
|
3343
|
+
}
|
|
3344
|
+
|
|
3011
3345
|
// src/viewer/hooks/useComments.ts
|
|
3012
3346
|
function useComments({
|
|
3013
3347
|
slides,
|
|
@@ -3020,11 +3354,33 @@ function useComments({
|
|
|
3020
3354
|
const [commentDraftBySlideId, setCommentDraftBySlideId] = useState({});
|
|
3021
3355
|
const [editingCommentIdBySlideId, setEditingCommentIdBySlideId] = useState({});
|
|
3022
3356
|
const [commentEditDraftByCommentId, setCommentEditDraftByCommentId] = useState({});
|
|
3023
|
-
const
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3357
|
+
const {
|
|
3358
|
+
commentDraftMentionsBySlideId,
|
|
3359
|
+
replyDraftMentionsByCommentId,
|
|
3360
|
+
setCommentDraftMentions,
|
|
3361
|
+
setReplyDraftMentions,
|
|
3362
|
+
clearCommentDraftMentions,
|
|
3363
|
+
clearReplyDraftMentions
|
|
3364
|
+
} = useCommentMentionDrafts();
|
|
3365
|
+
const reply = useCommentReplyHandlers({
|
|
3366
|
+
slides,
|
|
3367
|
+
canEdit,
|
|
3368
|
+
userName,
|
|
3369
|
+
onUpdateSlides,
|
|
3370
|
+
onMarkDirty,
|
|
3371
|
+
replyDraftMentionsByCommentId,
|
|
3372
|
+
setReplyDraftMentions,
|
|
3373
|
+
clearReplyDraftMentions
|
|
3374
|
+
});
|
|
3375
|
+
const handleCommentDraftChange = useCallback(
|
|
3376
|
+
(slideId, draft, mentions) => {
|
|
3377
|
+
setCommentDraftBySlideId((prev) => ({ ...prev, [slideId]: draft }));
|
|
3378
|
+
if (mentions) {
|
|
3379
|
+
setCommentDraftMentions(slideId, mentions);
|
|
3380
|
+
}
|
|
3381
|
+
},
|
|
3382
|
+
[setCommentDraftMentions]
|
|
3383
|
+
);
|
|
3028
3384
|
const handleSetCommentEditDraft = useCallback((commentId, draft) => {
|
|
3029
3385
|
setCommentEditDraftByCommentId((prev) => ({
|
|
3030
3386
|
...prev,
|
|
@@ -3051,7 +3407,8 @@ function useComments({
|
|
|
3051
3407
|
slideIndex,
|
|
3052
3408
|
draft,
|
|
3053
3409
|
userName,
|
|
3054
|
-
selectedElementId ?? void 0
|
|
3410
|
+
selectedElementId ?? void 0,
|
|
3411
|
+
commentDraftMentionsBySlideId[slide.id]
|
|
3055
3412
|
);
|
|
3056
3413
|
didAdd = result.didAdd;
|
|
3057
3414
|
return result.slides;
|
|
@@ -3063,11 +3420,14 @@ function useComments({
|
|
|
3063
3420
|
...prev,
|
|
3064
3421
|
[slide.id]: ""
|
|
3065
3422
|
}));
|
|
3423
|
+
clearCommentDraftMentions(slide.id);
|
|
3066
3424
|
onMarkDirty();
|
|
3067
3425
|
},
|
|
3068
3426
|
[
|
|
3069
3427
|
canEdit,
|
|
3070
3428
|
commentDraftBySlideId,
|
|
3429
|
+
commentDraftMentionsBySlideId,
|
|
3430
|
+
clearCommentDraftMentions,
|
|
3071
3431
|
onMarkDirty,
|
|
3072
3432
|
onUpdateSlides,
|
|
3073
3433
|
selectedElementId,
|
|
@@ -3179,48 +3539,6 @@ function useComments({
|
|
|
3179
3539
|
},
|
|
3180
3540
|
[canEdit, onMarkDirty, onUpdateSlides, slides]
|
|
3181
3541
|
);
|
|
3182
|
-
const handleStartReply = useCallback((_slideIndex, commentId) => {
|
|
3183
|
-
setReplyingToCommentId(commentId);
|
|
3184
|
-
setReplyDraftByCommentId((prev) => ({ ...prev, [commentId]: "" }));
|
|
3185
|
-
}, []);
|
|
3186
|
-
const handleCancelReply = useCallback(() => {
|
|
3187
|
-
setReplyingToCommentId(null);
|
|
3188
|
-
}, []);
|
|
3189
|
-
const handleReplyDraftChange = useCallback((commentId, draft) => {
|
|
3190
|
-
setReplyDraftByCommentId((prev) => ({ ...prev, [commentId]: draft }));
|
|
3191
|
-
}, []);
|
|
3192
|
-
const handleSubmitReply = useCallback(
|
|
3193
|
-
(slideIndex, commentId) => {
|
|
3194
|
-
if (!canEdit) {
|
|
3195
|
-
return;
|
|
3196
|
-
}
|
|
3197
|
-
const slide = slides[slideIndex];
|
|
3198
|
-
if (!slide) {
|
|
3199
|
-
return;
|
|
3200
|
-
}
|
|
3201
|
-
const replyText = String(replyDraftByCommentId[commentId] || "").trim();
|
|
3202
|
-
if (replyText.length === 0) {
|
|
3203
|
-
return;
|
|
3204
|
-
}
|
|
3205
|
-
let didAdd = false;
|
|
3206
|
-
onUpdateSlides((prev) => {
|
|
3207
|
-
const result = addReplyToSlide(prev, slideIndex, commentId, replyText, userName);
|
|
3208
|
-
didAdd = result.didAdd;
|
|
3209
|
-
return result.slides;
|
|
3210
|
-
});
|
|
3211
|
-
if (!didAdd) {
|
|
3212
|
-
return;
|
|
3213
|
-
}
|
|
3214
|
-
setReplyingToCommentId(null);
|
|
3215
|
-
setReplyDraftByCommentId((prev) => {
|
|
3216
|
-
const next = { ...prev };
|
|
3217
|
-
delete next[commentId];
|
|
3218
|
-
return next;
|
|
3219
|
-
});
|
|
3220
|
-
onMarkDirty();
|
|
3221
|
-
},
|
|
3222
|
-
[canEdit, onMarkDirty, onUpdateSlides, replyDraftByCommentId, slides, userName]
|
|
3223
|
-
);
|
|
3224
3542
|
useEffect(() => {
|
|
3225
3543
|
const slideIds = new Set(slides.map((slide) => slide.id));
|
|
3226
3544
|
setCommentDraftBySlideId((prev) => {
|
|
@@ -3232,8 +3550,8 @@ function useComments({
|
|
|
3232
3550
|
commentDraftBySlideId,
|
|
3233
3551
|
editingCommentIdBySlideId,
|
|
3234
3552
|
commentEditDraftByCommentId,
|
|
3235
|
-
|
|
3236
|
-
|
|
3553
|
+
commentDraftMentionsBySlideId,
|
|
3554
|
+
replyDraftMentionsByCommentId,
|
|
3237
3555
|
handleCommentDraftChange,
|
|
3238
3556
|
handleAddSlideComment,
|
|
3239
3557
|
handleDeleteSlideComment,
|
|
@@ -3242,10 +3560,7 @@ function useComments({
|
|
|
3242
3560
|
handleSaveCommentEdit,
|
|
3243
3561
|
handleSetCommentEditDraft,
|
|
3244
3562
|
handleToggleCommentResolved,
|
|
3245
|
-
|
|
3246
|
-
handleCancelReply,
|
|
3247
|
-
handleReplyDraftChange,
|
|
3248
|
-
handleSubmitReply
|
|
3563
|
+
...reply
|
|
3249
3564
|
};
|
|
3250
3565
|
}
|
|
3251
3566
|
function buildElementLookup(templateElements, slideElements) {
|
|
@@ -3410,6 +3725,8 @@ function useViewerCoreState(_input) {
|
|
|
3410
3725
|
const [headerFooter, setHeaderFooter] = useState({});
|
|
3411
3726
|
const [layoutOptions, setLayoutOptions] = useState([]);
|
|
3412
3727
|
const [slideMasters, setSlideMasters] = useState([]);
|
|
3728
|
+
const [modernCommentAuthors, setModernCommentAuthors] = useState([]);
|
|
3729
|
+
const [recentColors, setRecentColors] = useState([]);
|
|
3413
3730
|
const [theme, setTheme] = useState();
|
|
3414
3731
|
const [tableStyleMap, setTableStyleMap] = useState();
|
|
3415
3732
|
const [themeOptions, setThemeOptions] = useState([]);
|
|
@@ -3503,6 +3820,10 @@ function useViewerCoreState(_input) {
|
|
|
3503
3820
|
setLayoutOptions,
|
|
3504
3821
|
slideMasters,
|
|
3505
3822
|
setSlideMasters,
|
|
3823
|
+
modernCommentAuthors,
|
|
3824
|
+
setModernCommentAuthors,
|
|
3825
|
+
recentColors,
|
|
3826
|
+
setRecentColors,
|
|
3506
3827
|
theme,
|
|
3507
3828
|
setTheme,
|
|
3508
3829
|
tableStyleMap,
|
|
@@ -3687,6 +4008,8 @@ function useLoadContent({
|
|
|
3687
4008
|
setHeaderFooter,
|
|
3688
4009
|
setLayoutOptions,
|
|
3689
4010
|
setSlideMasters,
|
|
4011
|
+
setModernCommentAuthors,
|
|
4012
|
+
setRecentColors,
|
|
3690
4013
|
setTheme,
|
|
3691
4014
|
setTableStyleMap,
|
|
3692
4015
|
setThemeOptions,
|
|
@@ -3708,6 +4031,8 @@ function useLoadContent({
|
|
|
3708
4031
|
setHasDigitalSignatures,
|
|
3709
4032
|
setDigitalSignatureCount,
|
|
3710
4033
|
setGuides,
|
|
4034
|
+
setReadOnlyRecommendation,
|
|
4035
|
+
setCompatToasts,
|
|
3711
4036
|
setLoading,
|
|
3712
4037
|
setError,
|
|
3713
4038
|
setIsDirty,
|
|
@@ -3837,6 +4162,8 @@ function useLoadContent({
|
|
|
3837
4162
|
setHeaderFooter(parsed.headerFooter ?? {});
|
|
3838
4163
|
setLayoutOptions(parsed.layoutOptions ?? []);
|
|
3839
4164
|
setSlideMasters(parsed.slideMasters ?? []);
|
|
4165
|
+
setModernCommentAuthors(parsed.modernCommentAuthors ?? []);
|
|
4166
|
+
setRecentColors(seedRecentColors({ mruColors: parsed.mruColors }));
|
|
3840
4167
|
setTheme(parsed.theme);
|
|
3841
4168
|
setTableStyleMap(nextTableStyleMap);
|
|
3842
4169
|
setThemeOptions(parsed.themeOptions ?? []);
|
|
@@ -3866,6 +4193,13 @@ function useLoadContent({
|
|
|
3866
4193
|
setHasDigitalSignatures(parsed.hasDigitalSignatures === true);
|
|
3867
4194
|
setDigitalSignatureCount(parsed.digitalSignatureCount ?? 0);
|
|
3868
4195
|
setGuides(buildInitialGuides(parsed.presentationGuides, parsed.slides[0]?.guides));
|
|
4196
|
+
setReadOnlyRecommendation(readOnlyRecommendation(parsed));
|
|
4197
|
+
setCompatToasts(
|
|
4198
|
+
compatibilityWarningToasts([
|
|
4199
|
+
...parsed.warnings ?? [],
|
|
4200
|
+
...parsed.slides.flatMap((slide) => slide.warnings ?? [])
|
|
4201
|
+
])
|
|
4202
|
+
);
|
|
3869
4203
|
setActiveSlideIndex(0);
|
|
3870
4204
|
clearSelection();
|
|
3871
4205
|
setIsDirty(false);
|
|
@@ -4282,6 +4616,42 @@ function useSectionOperations(input) {
|
|
|
4282
4616
|
};
|
|
4283
4617
|
}
|
|
4284
4618
|
|
|
4619
|
+
// src/viewer/utils/selection-handle-overlay.ts
|
|
4620
|
+
var VIEWPORT_SELECTOR = "[data-pptx-viewport]";
|
|
4621
|
+
function findSelectionHandleHost(elementNode, elementId) {
|
|
4622
|
+
const scope = elementNode.closest(VIEWPORT_SELECTOR) ?? elementNode.parentElement;
|
|
4623
|
+
if (!scope) {
|
|
4624
|
+
return null;
|
|
4625
|
+
}
|
|
4626
|
+
for (const candidate of scope.querySelectorAll("[data-pptx-handle-for]")) {
|
|
4627
|
+
if (candidate.getAttribute("data-pptx-handle-for") === elementId) {
|
|
4628
|
+
return candidate;
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4631
|
+
return null;
|
|
4632
|
+
}
|
|
4633
|
+
function syncSelectionHandleOverlay(elementNode, elementId, geometry) {
|
|
4634
|
+
const host = findSelectionHandleHost(elementNode, elementId);
|
|
4635
|
+
if (!host) {
|
|
4636
|
+
return;
|
|
4637
|
+
}
|
|
4638
|
+
if (geometry.x !== void 0) {
|
|
4639
|
+
host.style.left = `${geometry.x}px`;
|
|
4640
|
+
}
|
|
4641
|
+
if (geometry.y !== void 0) {
|
|
4642
|
+
host.style.top = `${geometry.y}px`;
|
|
4643
|
+
}
|
|
4644
|
+
if (geometry.width !== void 0) {
|
|
4645
|
+
host.style.width = `${geometry.width}px`;
|
|
4646
|
+
}
|
|
4647
|
+
if (geometry.height !== void 0) {
|
|
4648
|
+
host.style.height = `${geometry.height}px`;
|
|
4649
|
+
}
|
|
4650
|
+
if (geometry.transform !== void 0) {
|
|
4651
|
+
host.style.transform = geometry.transform;
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4654
|
+
|
|
4285
4655
|
// src/viewer/hooks/pointer-move-handlers.ts
|
|
4286
4656
|
function computeResizeGeometry(handle, startX, startY, startWidth, startHeight, dx, dy, snapToGrid, gridSpacingPx, lockAspect = false) {
|
|
4287
4657
|
const startBox = { x: startX, y: startY, width: startWidth, height: startHeight };
|
|
@@ -4438,8 +4808,11 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
|
|
|
4438
4808
|
for (const [id, domEl] of drag.domEls) {
|
|
4439
4809
|
const start = drag.startPositionsById[id];
|
|
4440
4810
|
if (start) {
|
|
4441
|
-
|
|
4442
|
-
|
|
4811
|
+
const x = start.x + appliedDx;
|
|
4812
|
+
const y = start.y + appliedDy;
|
|
4813
|
+
domEl.style.left = `${x}px`;
|
|
4814
|
+
domEl.style.top = `${y}px`;
|
|
4815
|
+
syncSelectionHandleOverlay(domEl, id, { x, y });
|
|
4443
4816
|
}
|
|
4444
4817
|
}
|
|
4445
4818
|
if (live) {
|
|
@@ -4477,18 +4850,21 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4477
4850
|
rs.lastY = geo.y;
|
|
4478
4851
|
rs.lastWidth = geo.width;
|
|
4479
4852
|
rs.lastHeight = geo.height;
|
|
4853
|
+
const width = Math.max(geo.width, MIN_ELEMENT_SIZE);
|
|
4854
|
+
const height = Math.max(geo.height, MIN_ELEMENT_SIZE);
|
|
4480
4855
|
if (rs.domEl) {
|
|
4481
4856
|
rs.domEl.style.left = `${geo.x}px`;
|
|
4482
4857
|
rs.domEl.style.top = `${geo.y}px`;
|
|
4483
|
-
rs.domEl.style.width = `${
|
|
4484
|
-
rs.domEl.style.height = `${
|
|
4858
|
+
rs.domEl.style.width = `${width}px`;
|
|
4859
|
+
rs.domEl.style.height = `${height}px`;
|
|
4860
|
+
syncSelectionHandleOverlay(rs.domEl, rs.elementId, { x: geo.x, y: geo.y, width, height });
|
|
4485
4861
|
}
|
|
4486
4862
|
if (live) {
|
|
4487
4863
|
publishLiveGeometry(live.patcher, live.slideId, rs.elementId, {
|
|
4488
4864
|
x: geo.x,
|
|
4489
4865
|
y: geo.y,
|
|
4490
|
-
width
|
|
4491
|
-
height
|
|
4866
|
+
width,
|
|
4867
|
+
height
|
|
4492
4868
|
});
|
|
4493
4869
|
}
|
|
4494
4870
|
}
|
|
@@ -7447,7 +7823,7 @@ function usePrintHandlers(input) {
|
|
|
7447
7823
|
printWindow,
|
|
7448
7824
|
buildPrintHtmlDocument({
|
|
7449
7825
|
title: `Handout ${spp} per page`,
|
|
7450
|
-
bodyHtml: buildHandoutsHtml(slideImages, slideIndices, spp),
|
|
7826
|
+
bodyHtml: buildHandoutsHtml(slideImages, slideIndices, spp, pptxData?.handoutMaster),
|
|
7451
7827
|
orientation: "portrait",
|
|
7452
7828
|
colorFilter,
|
|
7453
7829
|
frameSlides: settings.frameSlides,
|
|
@@ -8104,9 +8480,10 @@ function useViewerDialogs(input) {
|
|
|
8104
8480
|
function computeGridSpacingPx2(documentGridSpacing) {
|
|
8105
8481
|
return computeGridSpacingPx(documentGridSpacing, GRID_SIZE);
|
|
8106
8482
|
}
|
|
8107
|
-
function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows) {
|
|
8483
|
+
function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows, presentationProperties) {
|
|
8108
8484
|
const activeShow = activeCustomShowId ? customShows.find((show) => show.id === activeCustomShowId) : void 0;
|
|
8109
|
-
|
|
8485
|
+
const authoredRange = resolveAuthoredSlideRange(presentationProperties, slides.length);
|
|
8486
|
+
return resolveShowSlideIndexes(slides, activeShow, authoredRange);
|
|
8110
8487
|
}
|
|
8111
8488
|
function computeSlideSectionGroups(slides, sections) {
|
|
8112
8489
|
return groupSlidesBySection(sections, slides).map((group) => ({
|
|
@@ -8135,6 +8512,7 @@ function useDerivedSlideState(input) {
|
|
|
8135
8512
|
sections,
|
|
8136
8513
|
customShows,
|
|
8137
8514
|
activeCustomShowId,
|
|
8515
|
+
presentationProperties,
|
|
8138
8516
|
mode,
|
|
8139
8517
|
activeLayout,
|
|
8140
8518
|
activeMaster,
|
|
@@ -8145,8 +8523,12 @@ function useDerivedSlideState(input) {
|
|
|
8145
8523
|
[documentGridSpacing]
|
|
8146
8524
|
);
|
|
8147
8525
|
const visibleSlideIndexes = useMemo(
|
|
8148
|
-
() => computeVisibleSlideIndexes(slides, activeCustomShowId, customShows),
|
|
8149
|
-
[slides, activeCustomShowId, customShows]
|
|
8526
|
+
() => computeVisibleSlideIndexes(slides, activeCustomShowId, customShows, presentationProperties),
|
|
8527
|
+
[slides, activeCustomShowId, customShows, presentationProperties]
|
|
8528
|
+
);
|
|
8529
|
+
const authoredRange = useMemo(
|
|
8530
|
+
() => resolveAuthoredSlideRange(presentationProperties, slides.length),
|
|
8531
|
+
[presentationProperties, slides.length]
|
|
8150
8532
|
);
|
|
8151
8533
|
const slideSectionGroups = useMemo(
|
|
8152
8534
|
() => computeSlideSectionGroups(slides, sections).map((group) => {
|
|
@@ -8168,7 +8550,8 @@ function useDerivedSlideState(input) {
|
|
|
8168
8550
|
gridSpacingPx,
|
|
8169
8551
|
visibleSlideIndexes,
|
|
8170
8552
|
slideSectionGroups,
|
|
8171
|
-
masterPseudoSlide
|
|
8553
|
+
masterPseudoSlide,
|
|
8554
|
+
authoredRange
|
|
8172
8555
|
};
|
|
8173
8556
|
}
|
|
8174
8557
|
function useAnnotationHandlers(input) {
|
|
@@ -8306,6 +8689,7 @@ function useSerialize(input) {
|
|
|
8306
8689
|
guides,
|
|
8307
8690
|
headerFooter,
|
|
8308
8691
|
presentationProperties,
|
|
8692
|
+
viewProperties,
|
|
8309
8693
|
customShows,
|
|
8310
8694
|
sections,
|
|
8311
8695
|
coreProperties,
|
|
@@ -8367,6 +8751,7 @@ function useSerialize(input) {
|
|
|
8367
8751
|
slideSize: resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
8368
8752
|
headerFooter,
|
|
8369
8753
|
presentationProperties,
|
|
8754
|
+
viewProperties,
|
|
8370
8755
|
customShows: customShows.length > 0 ? customShows : void 0,
|
|
8371
8756
|
sections: sections.length > 0 ? sections : void 0,
|
|
8372
8757
|
coreProperties,
|
|
@@ -8386,6 +8771,7 @@ function useSerialize(input) {
|
|
|
8386
8771
|
slideSizeEmu,
|
|
8387
8772
|
headerFooter,
|
|
8388
8773
|
presentationProperties,
|
|
8774
|
+
viewProperties,
|
|
8389
8775
|
customShows,
|
|
8390
8776
|
sections,
|
|
8391
8777
|
coreProperties,
|
|
@@ -8456,6 +8842,7 @@ function usePresentationSetup(input) {
|
|
|
8456
8842
|
const {
|
|
8457
8843
|
mode,
|
|
8458
8844
|
slides,
|
|
8845
|
+
templateElementsBySlideId,
|
|
8459
8846
|
visibleSlideIndexes,
|
|
8460
8847
|
activeSlideIndex,
|
|
8461
8848
|
containerRef,
|
|
@@ -8469,7 +8856,10 @@ function usePresentationSetup(input) {
|
|
|
8469
8856
|
endWithBlackSlide = true,
|
|
8470
8857
|
promptKeepInkAnnotations = true,
|
|
8471
8858
|
popupToolbarEnabled = true,
|
|
8472
|
-
onToggleSubtitles
|
|
8859
|
+
onToggleSubtitles,
|
|
8860
|
+
customShows = [],
|
|
8861
|
+
activeCustomShowId = null,
|
|
8862
|
+
onSetActiveCustomShowId
|
|
8473
8863
|
} = input;
|
|
8474
8864
|
const actionSoundHandlerRef = useRef(null);
|
|
8475
8865
|
const exitModeHandlerRef = useRef(null);
|
|
@@ -8481,6 +8871,7 @@ function usePresentationSetup(input) {
|
|
|
8481
8871
|
const presentation = usePresentationMode({
|
|
8482
8872
|
mode,
|
|
8483
8873
|
slides,
|
|
8874
|
+
templateElementsBySlideId,
|
|
8484
8875
|
visibleSlideIndexes,
|
|
8485
8876
|
activeSlideIndex,
|
|
8486
8877
|
containerRef,
|
|
@@ -8558,7 +8949,10 @@ function usePresentationSetup(input) {
|
|
|
8558
8949
|
loopContinuously: shouldLoopContinuously(presentationProperties),
|
|
8559
8950
|
showWithAnimation: presentationProperties.showWithAnimation,
|
|
8560
8951
|
useTimings: presentationProperties.advanceMode !== "manual",
|
|
8561
|
-
endWithBlackSlide
|
|
8952
|
+
endWithBlackSlide,
|
|
8953
|
+
customShows,
|
|
8954
|
+
activeCustomShowId,
|
|
8955
|
+
onSetActiveCustomShowId
|
|
8562
8956
|
});
|
|
8563
8957
|
return {
|
|
8564
8958
|
presentation,
|
|
@@ -9042,7 +9436,9 @@ function useContentLifecycle(input) {
|
|
|
9042
9436
|
setIsEncryptedDialogOpen,
|
|
9043
9437
|
password,
|
|
9044
9438
|
onContentApplied,
|
|
9045
|
-
allowExternalImages
|
|
9439
|
+
allowExternalImages,
|
|
9440
|
+
setReadOnlyRecommendation,
|
|
9441
|
+
setCompatToasts
|
|
9046
9442
|
} = input;
|
|
9047
9443
|
const { handlerRef } = useLoadContent({
|
|
9048
9444
|
content,
|
|
@@ -9056,6 +9452,8 @@ function useContentLifecycle(input) {
|
|
|
9056
9452
|
setHeaderFooter: state.setHeaderFooter,
|
|
9057
9453
|
setLayoutOptions: state.setLayoutOptions,
|
|
9058
9454
|
setSlideMasters: state.setSlideMasters,
|
|
9455
|
+
setModernCommentAuthors: state.setModernCommentAuthors,
|
|
9456
|
+
setRecentColors: state.setRecentColors,
|
|
9059
9457
|
setTheme: state.setTheme,
|
|
9060
9458
|
setTableStyleMap: state.setTableStyleMap,
|
|
9061
9459
|
setThemeOptions: state.setThemeOptions,
|
|
@@ -9077,6 +9475,8 @@ function useContentLifecycle(input) {
|
|
|
9077
9475
|
setHasDigitalSignatures: state.setHasDigitalSignatures,
|
|
9078
9476
|
setDigitalSignatureCount: state.setDigitalSignatureCount,
|
|
9079
9477
|
setGuides: state.setGuides,
|
|
9478
|
+
setReadOnlyRecommendation,
|
|
9479
|
+
setCompatToasts,
|
|
9080
9480
|
setLoading: state.setLoading,
|
|
9081
9481
|
setError: state.setError,
|
|
9082
9482
|
setIsDirty: state.setIsDirty,
|
|
@@ -9097,6 +9497,7 @@ function useContentLifecycle(input) {
|
|
|
9097
9497
|
guides: state.guides,
|
|
9098
9498
|
headerFooter: state.headerFooter,
|
|
9099
9499
|
presentationProperties: state.presentationProperties,
|
|
9500
|
+
viewProperties: state.viewProperties,
|
|
9100
9501
|
customShows: state.customShows,
|
|
9101
9502
|
sections: state.sections,
|
|
9102
9503
|
coreProperties: state.coreProperties,
|
|
@@ -9152,6 +9553,16 @@ function useKeyboardShortcuts(input) {
|
|
|
9152
9553
|
inputRef.current = input;
|
|
9153
9554
|
const handleKeyDown = useCallback((e) => {
|
|
9154
9555
|
const current = inputRef.current;
|
|
9556
|
+
const startAction = mapSlideShowStartKey(e, { isPresenting: current.mode === "present" });
|
|
9557
|
+
if (startAction !== null) {
|
|
9558
|
+
e.preventDefault();
|
|
9559
|
+
if (startAction === "fromBeginning") {
|
|
9560
|
+
current.onStartShowFromBeginning();
|
|
9561
|
+
} else {
|
|
9562
|
+
current.onStartShowFromCurrent();
|
|
9563
|
+
}
|
|
9564
|
+
return;
|
|
9565
|
+
}
|
|
9155
9566
|
const { action, dx, dy } = mapEditorKey(e, {
|
|
9156
9567
|
canEdit: current.canEdit,
|
|
9157
9568
|
// The Slide Master view is an editing surface, not a viewing one.
|
|
@@ -9232,7 +9643,18 @@ function useKeyboardShortcuts(input) {
|
|
|
9232
9643
|
|
|
9233
9644
|
// src/viewer/hooks/useKeyboardShortcutWiring.ts
|
|
9234
9645
|
function useKeyboardShortcutWiring(input) {
|
|
9235
|
-
const {
|
|
9646
|
+
const {
|
|
9647
|
+
state,
|
|
9648
|
+
mode,
|
|
9649
|
+
canEdit,
|
|
9650
|
+
slides,
|
|
9651
|
+
activeSlide,
|
|
9652
|
+
ops,
|
|
9653
|
+
manipulation,
|
|
9654
|
+
history,
|
|
9655
|
+
onEnterPresentModeFromBeginning,
|
|
9656
|
+
onSetMode
|
|
9657
|
+
} = input;
|
|
9236
9658
|
useKeyboardShortcuts({
|
|
9237
9659
|
containerRef: state.containerRef,
|
|
9238
9660
|
mode,
|
|
@@ -9302,7 +9724,9 @@ function useKeyboardShortcutWiring(input) {
|
|
|
9302
9724
|
return;
|
|
9303
9725
|
}
|
|
9304
9726
|
state.setActiveSlideIndex((prev) => Math.min(slides.length - 1, prev + 1));
|
|
9305
|
-
}
|
|
9727
|
+
},
|
|
9728
|
+
onStartShowFromBeginning: onEnterPresentModeFromBeginning,
|
|
9729
|
+
onStartShowFromCurrent: () => onSetMode("present")
|
|
9306
9730
|
});
|
|
9307
9731
|
}
|
|
9308
9732
|
function useViewerIntegration(input) {
|
|
@@ -9322,6 +9746,8 @@ function useViewerIntegration(input) {
|
|
|
9322
9746
|
autosaveAllowed = true,
|
|
9323
9747
|
autosaveIntervalMs,
|
|
9324
9748
|
allowExternalImages,
|
|
9749
|
+
setReadOnlyRecommendation,
|
|
9750
|
+
setCompatToasts,
|
|
9325
9751
|
canEdit,
|
|
9326
9752
|
promptKeepInkAnnotations,
|
|
9327
9753
|
imageExportScale,
|
|
@@ -9390,7 +9816,9 @@ function useViewerIntegration(input) {
|
|
|
9390
9816
|
setIsEncryptedDialogOpen,
|
|
9391
9817
|
password: dialogs.presentationPassword ?? void 0,
|
|
9392
9818
|
onContentApplied: () => setLoadVersion((v) => v + 1),
|
|
9393
|
-
allowExternalImages
|
|
9819
|
+
allowExternalImages,
|
|
9820
|
+
setReadOnlyRecommendation,
|
|
9821
|
+
setCompatToasts
|
|
9394
9822
|
}
|
|
9395
9823
|
);
|
|
9396
9824
|
const { exportHandlers, printHandlers, themeHandlers, propertyHandlers } = useIOHandlers({
|
|
@@ -9625,7 +10053,9 @@ function useViewerIntegration(input) {
|
|
|
9625
10053
|
activeSlide,
|
|
9626
10054
|
ops: editorOps.ops,
|
|
9627
10055
|
manipulation: editorOps.manipulation,
|
|
9628
|
-
history
|
|
10056
|
+
history,
|
|
10057
|
+
onEnterPresentModeFromBeginning: presentation.enterPresentModeFromBeginning,
|
|
10058
|
+
onSetMode: handleSetMode
|
|
9629
10059
|
});
|
|
9630
10060
|
return {
|
|
9631
10061
|
exportHandlers,
|
|
@@ -10305,14 +10735,14 @@ function buildCanvasProps(input) {
|
|
|
10305
10735
|
}
|
|
10306
10736
|
safeOpenUrl(url);
|
|
10307
10737
|
};
|
|
10308
|
-
const handleActionClick = (
|
|
10738
|
+
const handleActionClick = (elementId, action) => {
|
|
10309
10739
|
if (mode === "present") {
|
|
10310
10740
|
const resolved = resolvePresentationAction(action, { slideCount: slides.length });
|
|
10311
10741
|
if (resolved.intent.kind === "openUrl") {
|
|
10312
10742
|
openExternalUrl(resolved.intent.url);
|
|
10313
10743
|
return;
|
|
10314
10744
|
}
|
|
10315
|
-
presentation.handlePresentationAction(action);
|
|
10745
|
+
presentation.handlePresentationAction(action, elementId);
|
|
10316
10746
|
} else if (action.url) {
|
|
10317
10747
|
openExternalUrl(action.url);
|
|
10318
10748
|
}
|
|
@@ -10521,7 +10951,8 @@ function buildToolbarProps(input) {
|
|
|
10521
10951
|
onOpenFile,
|
|
10522
10952
|
onOpenRecentFile,
|
|
10523
10953
|
fileName,
|
|
10524
|
-
hiddenActions
|
|
10954
|
+
hiddenActions,
|
|
10955
|
+
viewPreferencesSync
|
|
10525
10956
|
} = input;
|
|
10526
10957
|
const {
|
|
10527
10958
|
handleAddAnimation,
|
|
@@ -10605,9 +11036,9 @@ function buildToolbarProps(input) {
|
|
|
10605
11036
|
onSetSpellCheckEnabled: s.setSpellCheckEnabled,
|
|
10606
11037
|
onSetShowGrid: s.setShowGrid,
|
|
10607
11038
|
onSetShowRulers: s.setShowRulers,
|
|
10608
|
-
onSetShowGuides: s.setShowGuides,
|
|
10609
|
-
onSetSnapToGrid: s.setSnapToGrid,
|
|
10610
|
-
onSetSnapToShape: s.setSnapToShape,
|
|
11039
|
+
onSetShowGuides: viewPreferencesSync?.handleSetShowGuides ?? s.setShowGuides,
|
|
11040
|
+
onSetSnapToGrid: viewPreferencesSync?.handleSetSnapToGrid ?? s.setSnapToGrid,
|
|
11041
|
+
onSetSnapToShape: viewPreferencesSync?.handleSetSnapToShape ?? s.setSnapToShape,
|
|
10611
11042
|
onAddGuide: dialogs.handleAddGuide,
|
|
10612
11043
|
onAlignElements: manipulation.handleAlignElements,
|
|
10613
11044
|
onDistributeElements: manipulation.handleDistributeElements,
|
|
@@ -10794,6 +11225,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10794
11225
|
sections: state.sections,
|
|
10795
11226
|
customShows: state.customShows,
|
|
10796
11227
|
activeCustomShowId: state.activeCustomShowId,
|
|
11228
|
+
presentationProperties: state.presentationProperties,
|
|
10797
11229
|
mode,
|
|
10798
11230
|
activeLayout: state.activeLayout,
|
|
10799
11231
|
activeMaster: state.activeMaster,
|
|
@@ -10802,6 +11234,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10802
11234
|
const { presentation, annotations, actionSoundHandlerRef, setExitModeHandler } = usePresentationSetup({
|
|
10803
11235
|
mode,
|
|
10804
11236
|
slides,
|
|
11237
|
+
templateElementsBySlideId,
|
|
10805
11238
|
visibleSlideIndexes,
|
|
10806
11239
|
endWithBlackSlide: viewerOptions.advanced.slideShowEndWithBlackSlide,
|
|
10807
11240
|
// File > Options > Advanced > "Prompt to keep ink annotations when
|
|
@@ -10846,6 +11279,111 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10846
11279
|
viewerOptions
|
|
10847
11280
|
};
|
|
10848
11281
|
}
|
|
11282
|
+
function useCompatibilityToastsState() {
|
|
11283
|
+
const [toasts, setToasts] = useState([]);
|
|
11284
|
+
const dismiss = useCallback((id) => {
|
|
11285
|
+
setToasts((prev) => prev.filter((toast) => toast.id !== id));
|
|
11286
|
+
}, []);
|
|
11287
|
+
const dismissAll = useCallback(() => {
|
|
11288
|
+
setToasts([]);
|
|
11289
|
+
}, []);
|
|
11290
|
+
return { toasts, setToasts, dismiss, dismissAll };
|
|
11291
|
+
}
|
|
11292
|
+
function useReadOnlyRecommendationState(content) {
|
|
11293
|
+
const [recommendation, setRecommendation] = useState(
|
|
11294
|
+
() => readOnlyRecommendation(void 0)
|
|
11295
|
+
);
|
|
11296
|
+
const [bannerHidden, setBannerHidden] = useState(false);
|
|
11297
|
+
const [editAnywayActive, setEditAnywayActive] = useState(false);
|
|
11298
|
+
useEffect(() => {
|
|
11299
|
+
setBannerHidden(false);
|
|
11300
|
+
setEditAnywayActive(false);
|
|
11301
|
+
}, [content]);
|
|
11302
|
+
const editAnyway = useCallback(() => {
|
|
11303
|
+
setEditAnywayActive(true);
|
|
11304
|
+
setBannerHidden(true);
|
|
11305
|
+
}, []);
|
|
11306
|
+
const dismiss = useCallback(() => {
|
|
11307
|
+
setBannerHidden(true);
|
|
11308
|
+
}, []);
|
|
11309
|
+
return {
|
|
11310
|
+
recommendation,
|
|
11311
|
+
setRecommendation,
|
|
11312
|
+
/** Whether the viewer's `canEdit` should be forced off. */
|
|
11313
|
+
locked: recommendation.defaultReadOnly && !editAnywayActive,
|
|
11314
|
+
bannerVisible: recommendation.kind !== null && !bannerHidden,
|
|
11315
|
+
editAnyway,
|
|
11316
|
+
dismiss
|
|
11317
|
+
};
|
|
11318
|
+
}
|
|
11319
|
+
function useViewPreferencesSync(input) {
|
|
11320
|
+
const {
|
|
11321
|
+
loadVersion,
|
|
11322
|
+
viewProperties,
|
|
11323
|
+
setViewProperties,
|
|
11324
|
+
snapToGrid,
|
|
11325
|
+
setSnapToGrid,
|
|
11326
|
+
snapToShape,
|
|
11327
|
+
setSnapToShape,
|
|
11328
|
+
showGuides,
|
|
11329
|
+
setShowGuides
|
|
11330
|
+
} = input;
|
|
11331
|
+
useEffect(() => {
|
|
11332
|
+
const seeded = viewerPreferencesFromViewProperties(
|
|
11333
|
+
{ viewProperties },
|
|
11334
|
+
{ ...DEFAULT_VIEWER_PREFERENCES, snapToGrid, snapToObjects: snapToShape, showGuides }
|
|
11335
|
+
);
|
|
11336
|
+
setSnapToGrid(seeded.snapToGrid);
|
|
11337
|
+
setSnapToShape(seeded.snapToObjects ?? snapToShape);
|
|
11338
|
+
setShowGuides(seeded.showGuides ?? showGuides);
|
|
11339
|
+
}, [loadVersion]);
|
|
11340
|
+
const patchViewProperties = useCallback(
|
|
11341
|
+
(prefsOverride) => {
|
|
11342
|
+
setViewProperties((prev) => {
|
|
11343
|
+
const merged = {
|
|
11344
|
+
...DEFAULT_VIEWER_PREFERENCES,
|
|
11345
|
+
snapToGrid,
|
|
11346
|
+
snapToObjects: snapToShape,
|
|
11347
|
+
showGuides,
|
|
11348
|
+
gridSpacingCx: prev?.gridSpacing?.cx,
|
|
11349
|
+
gridSpacingCy: prev?.gridSpacing?.cy,
|
|
11350
|
+
...prefsOverride
|
|
11351
|
+
};
|
|
11352
|
+
const patch = viewPropertiesPatchFromPreferences(merged);
|
|
11353
|
+
return {
|
|
11354
|
+
...prev,
|
|
11355
|
+
slideViewPr: { ...prev?.slideViewPr, ...patch.slideViewPr },
|
|
11356
|
+
...patch.gridSpacing ? { gridSpacing: patch.gridSpacing } : {}
|
|
11357
|
+
};
|
|
11358
|
+
});
|
|
11359
|
+
},
|
|
11360
|
+
[setViewProperties, snapToGrid, snapToShape, showGuides]
|
|
11361
|
+
);
|
|
11362
|
+
const handleSetSnapToGrid = useCallback(
|
|
11363
|
+
(value) => {
|
|
11364
|
+
setSnapToGrid(value);
|
|
11365
|
+
patchViewProperties({ snapToGrid: value });
|
|
11366
|
+
},
|
|
11367
|
+
[setSnapToGrid, patchViewProperties]
|
|
11368
|
+
);
|
|
11369
|
+
const handleSetSnapToShape = useCallback(
|
|
11370
|
+
(value) => {
|
|
11371
|
+
setSnapToShape(value);
|
|
11372
|
+
patchViewProperties({ snapToObjects: value });
|
|
11373
|
+
},
|
|
11374
|
+
[setSnapToShape, patchViewProperties]
|
|
11375
|
+
);
|
|
11376
|
+
const handleSetShowGuides = useCallback(
|
|
11377
|
+
(value) => {
|
|
11378
|
+
setShowGuides(value);
|
|
11379
|
+
patchViewProperties({ showGuides: value });
|
|
11380
|
+
},
|
|
11381
|
+
[setShowGuides, patchViewProperties]
|
|
11382
|
+
);
|
|
11383
|
+
return { handleSetSnapToGrid, handleSetSnapToShape, handleSetShowGuides };
|
|
11384
|
+
}
|
|
11385
|
+
|
|
11386
|
+
// src/viewer/hooks/useViewerBuildingBlocksState.ts
|
|
10849
11387
|
function useViewerBuildingBlocksState(input) {
|
|
10850
11388
|
const { core, content, canEdit, filePath, autosaveEnabled, userName, handle, setContent } = input;
|
|
10851
11389
|
const {
|
|
@@ -10901,6 +11439,8 @@ function useViewerBuildingBlocksState(input) {
|
|
|
10901
11439
|
isDirty: state.isDirty,
|
|
10902
11440
|
history
|
|
10903
11441
|
});
|
|
11442
|
+
const readOnlyRec = useReadOnlyRecommendationState(content);
|
|
11443
|
+
const compatToastsState = useCompatibilityToastsState();
|
|
10904
11444
|
useEffect(() => {
|
|
10905
11445
|
state.setSelectedElementId(null);
|
|
10906
11446
|
state.setSelectedElementIds([]);
|
|
@@ -10931,7 +11471,8 @@ function useViewerBuildingBlocksState(input) {
|
|
|
10931
11471
|
handleSetMode,
|
|
10932
11472
|
handleEnterPresenterView,
|
|
10933
11473
|
handleEnterRehearsalMode,
|
|
10934
|
-
autosaveStatus
|
|
11474
|
+
autosaveStatus,
|
|
11475
|
+
loadVersion
|
|
10935
11476
|
} = useViewerIntegration({
|
|
10936
11477
|
state,
|
|
10937
11478
|
zoom,
|
|
@@ -10949,6 +11490,8 @@ function useViewerBuildingBlocksState(input) {
|
|
|
10949
11490
|
// applies, so the headless building-blocks API loads http(s) images
|
|
10950
11491
|
// under the same default-off, core-side SSRF/privacy guard.
|
|
10951
11492
|
allowExternalImages: viewerOptions.trust.allowExternalContent,
|
|
11493
|
+
setReadOnlyRecommendation: readOnlyRec.setRecommendation,
|
|
11494
|
+
setCompatToasts: compatToastsState.setToasts,
|
|
10952
11495
|
canEdit,
|
|
10953
11496
|
promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
|
|
10954
11497
|
imageExportScale,
|
|
@@ -10970,6 +11513,17 @@ function useViewerBuildingBlocksState(input) {
|
|
|
10970
11513
|
onSlideCountChange
|
|
10971
11514
|
});
|
|
10972
11515
|
setExitModeHandler(handleSetMode);
|
|
11516
|
+
const viewPreferencesSync = useViewPreferencesSync({
|
|
11517
|
+
loadVersion,
|
|
11518
|
+
viewProperties: state.viewProperties,
|
|
11519
|
+
setViewProperties: state.setViewProperties,
|
|
11520
|
+
snapToGrid: state.snapToGrid,
|
|
11521
|
+
setSnapToGrid: state.setSnapToGrid,
|
|
11522
|
+
snapToShape: state.snapToShape,
|
|
11523
|
+
setSnapToShape: state.setSnapToShape,
|
|
11524
|
+
showGuides: state.showGuides,
|
|
11525
|
+
setShowGuides: state.setShowGuides
|
|
11526
|
+
});
|
|
10973
11527
|
return {
|
|
10974
11528
|
dialogs,
|
|
10975
11529
|
editorOps,
|
|
@@ -10979,7 +11533,8 @@ function useViewerBuildingBlocksState(input) {
|
|
|
10979
11533
|
handleSetMode,
|
|
10980
11534
|
handleEnterPresenterView,
|
|
10981
11535
|
handleEnterRehearsalMode,
|
|
10982
|
-
autosaveStatus
|
|
11536
|
+
autosaveStatus,
|
|
11537
|
+
viewPreferencesSync
|
|
10983
11538
|
};
|
|
10984
11539
|
}
|
|
10985
11540
|
|
|
@@ -11052,7 +11607,8 @@ function useViewerBuildingBlocks(input) {
|
|
|
11052
11607
|
handleSetMode,
|
|
11053
11608
|
handleEnterPresenterView,
|
|
11054
11609
|
handleEnterRehearsalMode,
|
|
11055
|
-
autosaveStatus
|
|
11610
|
+
autosaveStatus,
|
|
11611
|
+
viewPreferencesSync
|
|
11056
11612
|
} = useViewerBuildingBlocksState({
|
|
11057
11613
|
core,
|
|
11058
11614
|
content,
|
|
@@ -11097,7 +11653,8 @@ function useViewerBuildingBlocks(input) {
|
|
|
11097
11653
|
onOpenFile,
|
|
11098
11654
|
onOpenRecentFile,
|
|
11099
11655
|
fileName,
|
|
11100
|
-
hiddenActions
|
|
11656
|
+
hiddenActions,
|
|
11657
|
+
viewPreferencesSync
|
|
11101
11658
|
});
|
|
11102
11659
|
const canvasProps = buildCanvasProps({
|
|
11103
11660
|
mode,
|
|
@@ -11195,4 +11752,4 @@ function useResizablePanels() {
|
|
|
11195
11752
|
};
|
|
11196
11753
|
}
|
|
11197
11754
|
|
|
11198
|
-
export { ACTION_VERB_MAP, MIN_TOUCH_TARGET, ViewerOptionsContext, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, renderToCanvas, scopeLayoutOptionsToActiveSlide, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useContentLifecycle, useDerivedElementState, useDerivedSlideState, useDialogCustomShows, useEditorHistory, useEditorOperations, useElementManipulation, useElementOperations, useExportHandlers, useExportSaveAs, useFindReplace, useFollowMode, useFontInjection, useGroupAlignLayerHandlers, useIOHandlers, useInsertElements, useIsMobile, useKeyboardInsets, useKeyboardShortcutWiring, useKeyboardShortcuts, useLayoutSwitching, useLoadContent, useMergeShapesHandler, useModalDismissDrag, usePointerHandlers, usePresenceTracking, usePresentationAnnotations, usePresentationKeyboard, usePresentationMode, usePresentationSetup, usePresenterWindow, usePrintHandlers, usePropertyHandlers, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };
|
|
11755
|
+
export { ACTION_VERB_MAP, MIN_TOUCH_TARGET, ViewerOptionsContext, computeToolbarVisibility, detectTargetType, isAudienceTab, parseAudienceNonce, parseEmailUrl, parseSlideFromUrl, renderToCanvas, safePrompt, scopeLayoutOptionsToActiveSlide, syncSelectionHandleOverlay, useAnimationPlayback, useAnnotationHandlers, useAudienceMode, useAutosave, useBroadcastFollower, useCanvasInteractions, useClipboardHandlers, useCollaborationLivePatch, useCollaborativeHistory, useCollaborativeState, useComments, useCompatibilityToastsState, useContentLifecycle, useDerivedElementState, useDerivedSlideState, useDialogCustomShows, useEditorHistory, useEditorOperations, useElementManipulation, useElementOperations, useExportHandlers, useExportSaveAs, useFindReplace, useFollowMode, useFontInjection, useGroupAlignLayerHandlers, useIOHandlers, useInsertElements, useIsMobile, useKeyboardInsets, useKeyboardShortcutWiring, useKeyboardShortcuts, useLayoutSwitching, useLoadContent, useMergeShapesHandler, useModalDismissDrag, usePointerHandlers, usePresenceTracking, usePresentationAnnotations, usePresentationKeyboard, usePresentationMode, usePresentationSetup, usePresenterWindow, usePrintHandlers, usePropertyHandlers, useReadOnlyRecommendationState, useRecoveryDetection, useReducedMotion, useRehearsalTimings, useResizablePanels, useSectionOperations, useSerialize, useSheetDismissDrag, useSlideManagement, useSlideNavigation, useSwipeNavigation, useTableOperations, useThemeHandlers, useThemeSwitching, useToolbarVisibility, useTouchGestures, useViewPreferencesSync, useViewerBuildingBlocks, useViewerCoreState, useViewerDialogs, useViewerIntegration, useViewerOptions, useViewerOptionsContext, useViewerState, useViewerUIState, useVirtualizedSlides, useYjsDocumentSync, useYjsProvider, useZoomNavigation, useZoomViewport };
|