@arbidocs/blocks 0.5.122 → 0.5.123
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/ConnectedNativeDocxComparison-QKHCYD6W.cjs +1 -1
- package/dist/{ConnectedPresentation-AU25OW25.cjs → ConnectedPresentation-5DOJ35XL.cjs} +7 -7
- package/dist/{ConnectedPresentation-AU25OW25.cjs.map → ConnectedPresentation-5DOJ35XL.cjs.map} +1 -1
- package/dist/{ConnectedSlidesTab-I75LKKN7.cjs → ConnectedSlidesTab-7YMEDGUU.cjs} +40 -18
- package/dist/ConnectedSlidesTab-7YMEDGUU.cjs.map +1 -0
- package/dist/ConnectedStreamedWordArtifact-AG62232A.cjs +1 -1
- package/dist/{FilesViewerDialog-4352KIOG.cjs → FilesViewerDialog-2QCCRWF2.cjs} +7 -7
- package/dist/{FilesViewerDialog-4352KIOG.cjs.map → FilesViewerDialog-2QCCRWF2.cjs.map} +1 -1
- package/dist/agents/index.cjs +176 -176
- package/dist/{chunk-LHWOKOMP.cjs → chunk-46P7IDBX.cjs} +3 -3
- package/dist/chunk-46P7IDBX.cjs.map +1 -0
- package/dist/{chunk-USNTRL22.cjs → chunk-DWMWEALB.cjs} +288 -214
- package/dist/chunk-DWMWEALB.cjs.map +1 -0
- package/dist/{chunk-UTJ223TI.cjs → chunk-JD2HX2BR.cjs} +98 -78
- package/dist/chunk-JD2HX2BR.cjs.map +1 -0
- package/dist/{chunk-QG2U2JGX.cjs → chunk-L4CIFLCU.cjs} +4 -4
- package/dist/{chunk-QG2U2JGX.cjs.map → chunk-L4CIFLCU.cjs.map} +1 -1
- package/dist/{chunk-CQQQIZU4.cjs → chunk-NQML7IUC.cjs} +3 -3
- package/dist/{chunk-CQQQIZU4.cjs.map → chunk-NQML7IUC.cjs.map} +1 -1
- package/dist/{chunk-WRLGLZIA.cjs → chunk-SNPK3R3O.cjs} +5 -5
- package/dist/{chunk-WRLGLZIA.cjs.map → chunk-SNPK3R3O.cjs.map} +1 -1
- package/dist/{chunk-XGM4VVNV.cjs → chunk-WV7BCGCK.cjs} +19 -19
- package/dist/{chunk-XGM4VVNV.cjs.map → chunk-WV7BCGCK.cjs.map} +1 -1
- package/dist/connect/docx.cjs +1 -1
- package/dist/connect/index.cjs +161 -161
- package/dist/connect/viewer.cjs +5 -5
- package/dist/connection/presentation/ConnectedSlidesTab.js +35 -13
- package/dist/connection/presentation/ConnectedSlidesTab.js.map +2 -2
- package/dist/connection/viewer/ConnectedDocumentViewer.js +51 -60
- package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
- package/dist/connection/viewer/ViewerMoreMenu.d.ts +18 -0
- package/dist/connection/viewer/ViewerMoreMenu.js +45 -0
- package/dist/connection/viewer/ViewerMoreMenu.js.map +7 -0
- package/dist/connection/viewer/pdf/PdfPassageHighlights.js +3 -2
- package/dist/connection/viewer/pdf/PdfPassageHighlights.js.map +2 -2
- package/dist/document-tools/DocumentToolButtons.js +2 -2
- package/dist/document-tools/DocumentToolButtons.js.map +2 -2
- package/dist/document-tools/index.cjs +13 -13
- package/dist/embed/index.cjs +2 -2
- package/dist/index.cjs +234 -234
- package/dist/presentation/BoxActionBar.d.ts +2 -2
- package/dist/presentation/BoxActionBar.js +62 -30
- package/dist/presentation/BoxActionBar.js.map +2 -2
- package/dist/presentation/ClipActionBar.js +60 -7
- package/dist/presentation/ClipActionBar.js.map +2 -2
- package/dist/presentation/ClipViewControls.d.ts +3 -3
- package/dist/presentation/ClipViewControls.js +59 -64
- package/dist/presentation/ClipViewControls.js.map +2 -2
- package/dist/presentation/SlidesEditor.js +56 -42
- package/dist/presentation/SlidesEditor.js.map +2 -2
- package/dist/presentation/StageItem.js +0 -5
- package/dist/presentation/StageItem.js.map +2 -2
- package/dist/styles.css +1 -1
- package/dist/workflow-canvas/index.cjs +12 -12
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/ConnectedSlidesTab-I75LKKN7.cjs.map +0 -1
- package/dist/chunk-LHWOKOMP.cjs.map +0 -1
- package/dist/chunk-USNTRL22.cjs.map +0 -1
- package/dist/chunk-UTJ223TI.cjs.map +0 -1
|
@@ -21,9 +21,9 @@ require('./chunk-3YEXZX4H.cjs');
|
|
|
21
21
|
require('./chunk-4PA6VCCR.cjs');
|
|
22
22
|
require('./chunk-WXUU3COI.cjs');
|
|
23
23
|
require('./chunk-AHDJXIUB.cjs');
|
|
24
|
+
require('./chunk-YVCOQHCE.cjs');
|
|
24
25
|
require('./chunk-RL2HI6NP.cjs');
|
|
25
26
|
require('./chunk-6UZC4XVV.cjs');
|
|
26
|
-
require('./chunk-YVCOQHCE.cjs');
|
|
27
27
|
require('./chunk-JV5TVUOU.cjs');
|
|
28
28
|
require('./chunk-ZVEW3JBT.cjs');
|
|
29
29
|
require('./chunk-VZOOGA47.cjs');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkDWMWEALB_cjs = require('./chunk-DWMWEALB.cjs');
|
|
5
5
|
require('./chunk-WOOOMTTA.cjs');
|
|
6
6
|
var chunk6OK7ESTL_cjs = require('./chunk-6OK7ESTL.cjs');
|
|
7
7
|
require('./chunk-5GCCUXMT.cjs');
|
|
@@ -223,14 +223,14 @@ function PresenterView({ onPresent, ...editor }) {
|
|
|
223
223
|
onDoubleClick: () => view && chunkWFMWKPGY_cjs.toggleFullscreen(view),
|
|
224
224
|
"data-testid": "presentation-present",
|
|
225
225
|
children: [
|
|
226
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
226
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkDWMWEALB_cjs.PresentationStage, {}),
|
|
227
227
|
/* @__PURE__ */ jsxRuntime.jsx(PresentControls, { view, shown: active })
|
|
228
228
|
]
|
|
229
229
|
}
|
|
230
230
|
);
|
|
231
231
|
}
|
|
232
232
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: rootRef, className: "h-full min-h-0", "data-testid": "presenter-view", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
233
|
-
|
|
233
|
+
chunkDWMWEALB_cjs.SlidesEditor,
|
|
234
234
|
{
|
|
235
235
|
...editor,
|
|
236
236
|
onPresent: onPresent ?? (() => chunk4TTX6ZNS_cjs.usePresentation.getState().setPresenting(true))
|
|
@@ -248,9 +248,9 @@ function PresentationWindow() {
|
|
|
248
248
|
const { user } = react.useArbiSession();
|
|
249
249
|
const userId = user?.external_id ?? null;
|
|
250
250
|
const shownFor = react$1.useRef(userId);
|
|
251
|
-
const { downloadFile } =
|
|
251
|
+
const { downloadFile } = chunkDWMWEALB_cjs.usePresentationFiles();
|
|
252
252
|
const logoId = chunk4TTX6ZNS_cjs.usePresentation((s) => s.theme.logo?.documentId ?? null);
|
|
253
|
-
const controller =
|
|
253
|
+
const controller = chunkDWMWEALB_cjs.usePresentationController(isOpen && !presenting);
|
|
254
254
|
react$1.useEffect(() => {
|
|
255
255
|
if (shownFor.current === userId) return;
|
|
256
256
|
shownFor.current = userId;
|
|
@@ -317,5 +317,5 @@ function PresentationWindow() {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
exports.ConnectedPresentation = ConnectedPresentation;
|
|
320
|
-
//# sourceMappingURL=ConnectedPresentation-
|
|
321
|
-
//# sourceMappingURL=ConnectedPresentation-
|
|
320
|
+
//# sourceMappingURL=ConnectedPresentation-5DOJ35XL.cjs.map
|
|
321
|
+
//# sourceMappingURL=ConnectedPresentation-5DOJ35XL.cjs.map
|
package/dist/{ConnectedPresentation-AU25OW25.cjs.map → ConnectedPresentation-5DOJ35XL.cjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/presentation/PresentControls.tsx","../src/presentation/PresenterView.tsx","../src/connection/presentation/ConnectedPresentation.tsx"],"names":["jsx","usePresentation","jsxs","cn","ChevronLeft","ChevronRight","EyeOff","toggleFullscreen","Maximize","Square","useEffect","STAGE_ASPECT","useState","useCallback","usePresenterKeys","PresentationStage","SlidesEditor","ConnectedDocumentToolsProvider","useArbiSessionStore","useArbiSessionState","isPanelOpen","PRESENTATION_PANEL","useArbiSession","useRef","usePresentationFiles","usePresentationController","presentationWindowOnlyPresents","ConnectedPanelHost","Fragment","Button","PanelLeftClose"],"mappings":"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","file":"ConnectedPresentation-AU25OW25.cjs","sourcesContent":["/**\n * The presented slides' controls, bottom left: previous and next slide (with where you are),\n * blank, full screen and stop. Like a slideshow's, they show while the pointer moves (or a key is\n * pressed) and fade after a moment, with the pointer, so a shared screen rarely shows them.\n */\n\nimport type { ReactNode } from 'react'\nimport { ChevronLeft, ChevronRight, EyeOff, Maximize, Square } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { usePresentation } from './store'\nimport { toggleFullscreen } from './usePresenterKeys'\n\nconst CONTROL =\n 'inline-flex size-8 items-center justify-center rounded-full text-white/85 hover:bg-white/15 hover:text-white disabled:opacity-30 disabled:hover:bg-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/60 pointer-coarse:size-11'\n\nfunction Control({\n label,\n onClick,\n disabled,\n children,\n testId,\n}: {\n label: string\n onClick: () => void\n disabled?: boolean\n children: ReactNode\n testId: string\n}) {\n return (\n <button\n type=\"button\"\n className={CONTROL}\n title={label}\n aria-label={label}\n disabled={disabled}\n onClick={(event) => {\n // A click on the controls is not a click on the slide (which goes to the next one).\n event.stopPropagation()\n onClick()\n }}\n data-testid={testId}\n >\n {children}\n </button>\n )\n}\n\nexport interface PresentControlsProps {\n /** The window presented in (full screen is that window's). */\n view: Window | null\n shown: boolean\n}\n\nexport function PresentControls({ view, shown }: PresentControlsProps) {\n const current = usePresentation((s) => s.current)\n const count = usePresentation((s) => s.slides.length)\n const blank = usePresentation((s) => s.blank)\n const actions = usePresentation.getState()\n return (\n <div\n className={cn(\n 'absolute bottom-4 left-4 z-30 flex items-center gap-0.5 rounded-full bg-black/60 p-1 text-white shadow-lg backdrop-blur transition-opacity duration-300',\n shown ? 'opacity-100' : 'pointer-events-none opacity-0'\n )}\n onPointerDown={(event) => event.stopPropagation()}\n onDoubleClick={(event) => event.stopPropagation()}\n role=\"toolbar\"\n aria-label=\"Slideshow\"\n data-testid=\"present-controls\"\n >\n <Control\n label=\"Previous slide (←)\"\n onClick={() => actions.goTo(current - 1)}\n disabled={current === 0}\n testId=\"present-previous\"\n >\n <ChevronLeft className=\"size-4\" />\n </Control>\n <span\n className=\"min-w-12 text-center text-xs tabular-nums text-white/85\"\n data-testid=\"present-position\"\n >\n {current + 1} / {count}\n </span>\n <Control\n label=\"Next slide (→, or click the slide)\"\n onClick={() => actions.goTo(current + 1)}\n disabled={current >= count - 1}\n testId=\"present-next\"\n >\n <ChevronRight className=\"size-4\" />\n </Control>\n <div className=\"mx-1 h-4 w-px bg-white/25\" />\n <Control\n label={blank ? 'Show the slide (B)' : 'Blank the screen (B)'}\n onClick={() => actions.setBlank(!blank)}\n testId=\"present-blank\"\n >\n <EyeOff className={cn('size-4', blank && 'text-amber-300')} />\n </Control>\n <Control\n label=\"Full screen (F)\"\n onClick={() => view && toggleFullscreen(view)}\n testId=\"present-fullscreen\"\n >\n <Maximize className=\"size-4\" />\n </Control>\n <Control\n label=\"Stop presenting (Esc)\"\n onClick={() => actions.setPresenting(false)}\n testId=\"present-stop\"\n >\n <Square className=\"size-3.5 fill-current\" />\n </Control>\n </div>\n )\n}\n","/**\n * The presentation in a window of its own, in one of two modes.\n *\n * Present: nothing but the stage on black, no controls and no pointer: what is shared in a call or\n * shown on a projector. Keys drive it (arrows / Page Up / Page Down change slide, B blanks, F or\n * double-click toggles full screen, Space plays videos, Escape stops presenting).\n *\n * Edit: the slides editor (`SlidesEditor`), the same as in the viewer's tab, when the presentation\n * is edited in its own window (beside the document its clips come from).\n */\n\nimport { useCallback, useEffect, useState } from 'react'\nimport { PresentationStage } from './PresentationStage'\nimport { SlidesEditor, type SlidesEditorProps } from './SlidesEditor'\nimport { STAGE_ASPECT } from './model'\nimport { usePresentation } from './store'\nimport { toggleFullscreen, usePresenterKeys } from './usePresenterKeys'\nimport { PresentControls } from './PresentControls'\n\n/** The presenting window's page width, at most (smaller on a small screen). */\nconst PRESENT_WIDTH = 1280\n\n/**\n * While presenting in a pop-out, its page is made 16:9 and wide enough to share sharply, so a\n * shared window is all stage with no bars; editing again gives the window back its size. Only a\n * pop-out (a window this app opened) can be resized; the app's own window is left alone.\n */\nfunction useStageShapedWindow(view: Window | null, presenting: boolean) {\n useEffect(() => {\n if (!view || !presenting || !view.opener) return\n const before = { width: view.outerWidth, height: view.outerHeight }\n const chromeWidth = view.outerWidth - view.innerWidth\n const chromeHeight = view.outerHeight - view.innerHeight\n // Wide enough for a sharp share (a call receives about what the window shows), and 16:9.\n const width = Math.max(\n view.innerWidth,\n Math.min(PRESENT_WIDTH, Math.round((view.screen.availWidth - chromeWidth) * 0.6))\n )\n const height = Math.min(\n Math.round(width / STAGE_ASPECT),\n view.screen.availHeight - chromeHeight\n )\n try {\n view.resizeTo(Math.round(height * STAGE_ASPECT) + chromeWidth, height + chromeHeight)\n } catch {\n return // not resizable: the stage letterboxes in black\n }\n return () => {\n try {\n if (!view.closed) view.resizeTo(before.width, before.height)\n } catch {\n // gone or not resizable\n }\n }\n }, [view, presenting])\n}\n\n/** How long the pointer (or a key) has to rest before the controls fade. */\nconst IDLE_MS = 2200\n\n/** The pointer has moved (or a key was pressed) in `view` within the last moment. */\nfunction usePointerActive(view: Window | null): boolean {\n const [active, setActive] = useState(true)\n useEffect(() => {\n if (!view) return\n setActive(true)\n let timer = view.setTimeout(() => setActive(false), IDLE_MS)\n const wake = () => {\n setActive(true)\n view.clearTimeout(timer)\n timer = view.setTimeout(() => setActive(false), IDLE_MS)\n }\n view.addEventListener('pointermove', wake)\n view.addEventListener('keydown', wake)\n return () => {\n view.clearTimeout(timer)\n view.removeEventListener('pointermove', wake)\n view.removeEventListener('keydown', wake)\n }\n }, [view])\n return active\n}\n\nexport type PresenterViewProps = Omit<SlidesEditorProps, 'onPresent'> & {\n /** Present (default: here, in this window). */\n onPresent?: () => void\n}\n\nexport function PresenterView({ onPresent, ...editor }: PresenterViewProps) {\n const presenting = usePresentation((s) => s.presenting)\n const [view, setView] = useState<Window | null>(null)\n // The keys work in whichever window the presenter is in.\n const rootRef = useCallback((node: HTMLDivElement | null) => {\n if (node) setView(node.ownerDocument.defaultView)\n }, [])\n usePresenterKeys(presenting ? view : null, true)\n useStageShapedWindow(view, presenting)\n\n const active = usePointerActive(presenting ? view : null)\n\n if (presenting) {\n return (\n <div\n ref={rootRef}\n className=\"relative h-full w-full select-none bg-black\"\n // The pointer shows while it moves, with the controls; idle, nothing but the slide.\n style={{ cursor: active ? 'default' : 'none' }}\n // A click on the slide goes to the next one, as in a slideshow.\n onClick={() => {\n const state = usePresentation.getState()\n state.goTo(state.current + 1)\n }}\n onDoubleClick={() => view && toggleFullscreen(view)}\n data-testid=\"presentation-present\"\n >\n <PresentationStage />\n <PresentControls view={view} shown={active} />\n </div>\n )\n }\n return (\n <div ref={rootRef} className=\"h-full min-h-0\" data-testid=\"presenter-view\">\n <SlidesEditor\n {...editor}\n onPresent={onPresent ?? (() => usePresentation.getState().setPresenting(true))}\n />\n </div>\n )\n}\n","/**\n * The presentation's own window, mounted once by the app shell (the session's `PRESENTATION_PANEL`,\n * a pop-out). It presents: the slides alone, what is shared in a call or put full screen; or, when\n * the editor is popped out of the viewer's slides tab, it edits there, beside the documents its\n * clips come from. A window opened only to present closes when presenting ends.\n *\n * It also keeps what the presentation needs wherever it is edited: the theme's logo image, read\n * when the logo changes; and a clean slate when the session signs out or another user signs in\n * (the presentation holds decrypted files in memory).\n */\n\nimport { useCallback, useEffect, useRef } from 'react'\nimport { PanelLeftClose } from 'lucide-react'\nimport {\n isPanelOpen,\n useArbiSession,\n useArbiSessionState,\n useArbiSessionStore,\n} from '@arbidocs/react'\nimport { Button } from '@arbidocs/react/ui'\nimport { ConnectedPanelHost } from '../panels/ConnectedPanelHost'\nimport { ConnectedDocumentToolsProvider } from '../viewer/ConnectedDocumentToolsProvider'\nimport { PRESENTATION_PANEL, presentationWindowOnlyPresents } from '../../presentation/panel-id'\nimport { PresenterView } from '../../presentation/PresenterView'\nimport { usePresentation } from '../../presentation/store'\nimport { usePresentationController } from './usePresentationController'\nimport { usePresentationFiles } from './usePresentationFiles'\n\n/** The presentation's window, with the document tools it needs (sources, redactions). */\nexport function ConnectedPresentation() {\n return (\n <ConnectedDocumentToolsProvider>\n <PresentationWindow />\n </ConnectedDocumentToolsProvider>\n )\n}\n\nfunction PresentationWindow() {\n const session = useArbiSessionStore()\n const notify = usePresentation((s) => s.notify)\n const presenting = usePresentation((s) => s.presenting)\n const isOpen = useArbiSessionState((state) => isPanelOpen(state, PRESENTATION_PANEL))\n const { user } = useArbiSession()\n const userId = user?.external_id ?? null\n const shownFor = useRef(userId)\n const { downloadFile } = usePresentationFiles()\n const logoId = usePresentation((s) => s.theme.logo?.documentId ?? null)\n const controller = usePresentationController(isOpen && !presenting)\n\n useEffect(() => {\n if (shownFor.current === userId) return\n shownFor.current = userId\n usePresentation.getState().reset()\n session.closePanel(PRESENTATION_PANEL)\n }, [userId, session])\n\n // The theme's logo image, fetched whenever the logo changes (the theme keeps a reference only).\n useEffect(() => {\n if (!logoId) return\n let current = true\n downloadFile(logoId)\n .then((image) => current && usePresentation.getState().setLogoImage(image))\n .catch(() => current && notify('The logo could not be read', 'error'))\n return () => {\n current = false\n }\n }, [logoId, downloadFile, notify])\n\n // A closed window is not presenting.\n useEffect(() => {\n if (!isOpen) usePresentation.getState().setPresenting(false)\n }, [isOpen])\n\n // Opened only to present: closed when presenting ends (Escape).\n const wasPresenting = useRef(presenting)\n useEffect(() => {\n if (wasPresenting.current && !presenting && isOpen && presentationWindowOnlyPresents()) {\n session.closePanel(PRESENTATION_PANEL)\n }\n wasPresenting.current = presenting\n }, [presenting, isOpen, session])\n\n const onClose = useCallback(() => session.closePanel(PRESENTATION_PANEL), [session])\n\n return (\n <ConnectedPanelHost\n panelId={PRESENTATION_PANEL}\n isOpen={isOpen}\n onClose={onClose}\n title=\"Presentation\"\n defaultMode=\"popout\"\n defaultWidth={960}\n closeTestId=\"presentation-panel-close\"\n >\n {/* Inside the panel, so its dialogs open in its window. */}\n {() => (\n <>\n {!presenting && controller.dialogs}\n <PresenterView\n {...controller.editor}\n actions={\n <>\n {controller.editor.actions}\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"size-8 text-muted-foreground hover:text-foreground pointer-coarse:size-11\"\n title=\"Back into the app's viewer\"\n aria-label=\"Back to the viewer\"\n onClick={onClose}\n data-testid=\"presentation-pop-in\"\n >\n <PanelLeftClose className=\"size-4\" />\n </Button>\n </>\n }\n />\n </>\n )}\n </ConnectedPanelHost>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/presentation/PresentControls.tsx","../src/presentation/PresenterView.tsx","../src/connection/presentation/ConnectedPresentation.tsx"],"names":["jsx","usePresentation","jsxs","cn","ChevronLeft","ChevronRight","EyeOff","toggleFullscreen","Maximize","Square","useEffect","STAGE_ASPECT","useState","useCallback","usePresenterKeys","PresentationStage","SlidesEditor","ConnectedDocumentToolsProvider","useArbiSessionStore","useArbiSessionState","isPanelOpen","PRESENTATION_PANEL","useArbiSession","useRef","usePresentationFiles","usePresentationController","presentationWindowOnlyPresents","ConnectedPanelHost","Fragment","Button","PanelLeftClose"],"mappings":"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","file":"ConnectedPresentation-5DOJ35XL.cjs","sourcesContent":["/**\n * The presented slides' controls, bottom left: previous and next slide (with where you are),\n * blank, full screen and stop. Like a slideshow's, they show while the pointer moves (or a key is\n * pressed) and fade after a moment, with the pointer, so a shared screen rarely shows them.\n */\n\nimport type { ReactNode } from 'react'\nimport { ChevronLeft, ChevronRight, EyeOff, Maximize, Square } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { usePresentation } from './store'\nimport { toggleFullscreen } from './usePresenterKeys'\n\nconst CONTROL =\n 'inline-flex size-8 items-center justify-center rounded-full text-white/85 hover:bg-white/15 hover:text-white disabled:opacity-30 disabled:hover:bg-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/60 pointer-coarse:size-11'\n\nfunction Control({\n label,\n onClick,\n disabled,\n children,\n testId,\n}: {\n label: string\n onClick: () => void\n disabled?: boolean\n children: ReactNode\n testId: string\n}) {\n return (\n <button\n type=\"button\"\n className={CONTROL}\n title={label}\n aria-label={label}\n disabled={disabled}\n onClick={(event) => {\n // A click on the controls is not a click on the slide (which goes to the next one).\n event.stopPropagation()\n onClick()\n }}\n data-testid={testId}\n >\n {children}\n </button>\n )\n}\n\nexport interface PresentControlsProps {\n /** The window presented in (full screen is that window's). */\n view: Window | null\n shown: boolean\n}\n\nexport function PresentControls({ view, shown }: PresentControlsProps) {\n const current = usePresentation((s) => s.current)\n const count = usePresentation((s) => s.slides.length)\n const blank = usePresentation((s) => s.blank)\n const actions = usePresentation.getState()\n return (\n <div\n className={cn(\n 'absolute bottom-4 left-4 z-30 flex items-center gap-0.5 rounded-full bg-black/60 p-1 text-white shadow-lg backdrop-blur transition-opacity duration-300',\n shown ? 'opacity-100' : 'pointer-events-none opacity-0'\n )}\n onPointerDown={(event) => event.stopPropagation()}\n onDoubleClick={(event) => event.stopPropagation()}\n role=\"toolbar\"\n aria-label=\"Slideshow\"\n data-testid=\"present-controls\"\n >\n <Control\n label=\"Previous slide (←)\"\n onClick={() => actions.goTo(current - 1)}\n disabled={current === 0}\n testId=\"present-previous\"\n >\n <ChevronLeft className=\"size-4\" />\n </Control>\n <span\n className=\"min-w-12 text-center text-xs tabular-nums text-white/85\"\n data-testid=\"present-position\"\n >\n {current + 1} / {count}\n </span>\n <Control\n label=\"Next slide (→, or click the slide)\"\n onClick={() => actions.goTo(current + 1)}\n disabled={current >= count - 1}\n testId=\"present-next\"\n >\n <ChevronRight className=\"size-4\" />\n </Control>\n <div className=\"mx-1 h-4 w-px bg-white/25\" />\n <Control\n label={blank ? 'Show the slide (B)' : 'Blank the screen (B)'}\n onClick={() => actions.setBlank(!blank)}\n testId=\"present-blank\"\n >\n <EyeOff className={cn('size-4', blank && 'text-amber-300')} />\n </Control>\n <Control\n label=\"Full screen (F)\"\n onClick={() => view && toggleFullscreen(view)}\n testId=\"present-fullscreen\"\n >\n <Maximize className=\"size-4\" />\n </Control>\n <Control\n label=\"Stop presenting (Esc)\"\n onClick={() => actions.setPresenting(false)}\n testId=\"present-stop\"\n >\n <Square className=\"size-3.5 fill-current\" />\n </Control>\n </div>\n )\n}\n","/**\n * The presentation in a window of its own, in one of two modes.\n *\n * Present: nothing but the stage on black, no controls and no pointer: what is shared in a call or\n * shown on a projector. Keys drive it (arrows / Page Up / Page Down change slide, B blanks, F or\n * double-click toggles full screen, Space plays videos, Escape stops presenting).\n *\n * Edit: the slides editor (`SlidesEditor`), the same as in the viewer's tab, when the presentation\n * is edited in its own window (beside the document its clips come from).\n */\n\nimport { useCallback, useEffect, useState } from 'react'\nimport { PresentationStage } from './PresentationStage'\nimport { SlidesEditor, type SlidesEditorProps } from './SlidesEditor'\nimport { STAGE_ASPECT } from './model'\nimport { usePresentation } from './store'\nimport { toggleFullscreen, usePresenterKeys } from './usePresenterKeys'\nimport { PresentControls } from './PresentControls'\n\n/** The presenting window's page width, at most (smaller on a small screen). */\nconst PRESENT_WIDTH = 1280\n\n/**\n * While presenting in a pop-out, its page is made 16:9 and wide enough to share sharply, so a\n * shared window is all stage with no bars; editing again gives the window back its size. Only a\n * pop-out (a window this app opened) can be resized; the app's own window is left alone.\n */\nfunction useStageShapedWindow(view: Window | null, presenting: boolean) {\n useEffect(() => {\n if (!view || !presenting || !view.opener) return\n const before = { width: view.outerWidth, height: view.outerHeight }\n const chromeWidth = view.outerWidth - view.innerWidth\n const chromeHeight = view.outerHeight - view.innerHeight\n // Wide enough for a sharp share (a call receives about what the window shows), and 16:9.\n const width = Math.max(\n view.innerWidth,\n Math.min(PRESENT_WIDTH, Math.round((view.screen.availWidth - chromeWidth) * 0.6))\n )\n const height = Math.min(\n Math.round(width / STAGE_ASPECT),\n view.screen.availHeight - chromeHeight\n )\n try {\n view.resizeTo(Math.round(height * STAGE_ASPECT) + chromeWidth, height + chromeHeight)\n } catch {\n return // not resizable: the stage letterboxes in black\n }\n return () => {\n try {\n if (!view.closed) view.resizeTo(before.width, before.height)\n } catch {\n // gone or not resizable\n }\n }\n }, [view, presenting])\n}\n\n/** How long the pointer (or a key) has to rest before the controls fade. */\nconst IDLE_MS = 2200\n\n/** The pointer has moved (or a key was pressed) in `view` within the last moment. */\nfunction usePointerActive(view: Window | null): boolean {\n const [active, setActive] = useState(true)\n useEffect(() => {\n if (!view) return\n setActive(true)\n let timer = view.setTimeout(() => setActive(false), IDLE_MS)\n const wake = () => {\n setActive(true)\n view.clearTimeout(timer)\n timer = view.setTimeout(() => setActive(false), IDLE_MS)\n }\n view.addEventListener('pointermove', wake)\n view.addEventListener('keydown', wake)\n return () => {\n view.clearTimeout(timer)\n view.removeEventListener('pointermove', wake)\n view.removeEventListener('keydown', wake)\n }\n }, [view])\n return active\n}\n\nexport type PresenterViewProps = Omit<SlidesEditorProps, 'onPresent'> & {\n /** Present (default: here, in this window). */\n onPresent?: () => void\n}\n\nexport function PresenterView({ onPresent, ...editor }: PresenterViewProps) {\n const presenting = usePresentation((s) => s.presenting)\n const [view, setView] = useState<Window | null>(null)\n // The keys work in whichever window the presenter is in.\n const rootRef = useCallback((node: HTMLDivElement | null) => {\n if (node) setView(node.ownerDocument.defaultView)\n }, [])\n usePresenterKeys(presenting ? view : null, true)\n useStageShapedWindow(view, presenting)\n\n const active = usePointerActive(presenting ? view : null)\n\n if (presenting) {\n return (\n <div\n ref={rootRef}\n className=\"relative h-full w-full select-none bg-black\"\n // The pointer shows while it moves, with the controls; idle, nothing but the slide.\n style={{ cursor: active ? 'default' : 'none' }}\n // A click on the slide goes to the next one, as in a slideshow.\n onClick={() => {\n const state = usePresentation.getState()\n state.goTo(state.current + 1)\n }}\n onDoubleClick={() => view && toggleFullscreen(view)}\n data-testid=\"presentation-present\"\n >\n <PresentationStage />\n <PresentControls view={view} shown={active} />\n </div>\n )\n }\n return (\n <div ref={rootRef} className=\"h-full min-h-0\" data-testid=\"presenter-view\">\n <SlidesEditor\n {...editor}\n onPresent={onPresent ?? (() => usePresentation.getState().setPresenting(true))}\n />\n </div>\n )\n}\n","/**\n * The presentation's own window, mounted once by the app shell (the session's `PRESENTATION_PANEL`,\n * a pop-out). It presents: the slides alone, what is shared in a call or put full screen; or, when\n * the editor is popped out of the viewer's slides tab, it edits there, beside the documents its\n * clips come from. A window opened only to present closes when presenting ends.\n *\n * It also keeps what the presentation needs wherever it is edited: the theme's logo image, read\n * when the logo changes; and a clean slate when the session signs out or another user signs in\n * (the presentation holds decrypted files in memory).\n */\n\nimport { useCallback, useEffect, useRef } from 'react'\nimport { PanelLeftClose } from 'lucide-react'\nimport {\n isPanelOpen,\n useArbiSession,\n useArbiSessionState,\n useArbiSessionStore,\n} from '@arbidocs/react'\nimport { Button } from '@arbidocs/react/ui'\nimport { ConnectedPanelHost } from '../panels/ConnectedPanelHost'\nimport { ConnectedDocumentToolsProvider } from '../viewer/ConnectedDocumentToolsProvider'\nimport { PRESENTATION_PANEL, presentationWindowOnlyPresents } from '../../presentation/panel-id'\nimport { PresenterView } from '../../presentation/PresenterView'\nimport { usePresentation } from '../../presentation/store'\nimport { usePresentationController } from './usePresentationController'\nimport { usePresentationFiles } from './usePresentationFiles'\n\n/** The presentation's window, with the document tools it needs (sources, redactions). */\nexport function ConnectedPresentation() {\n return (\n <ConnectedDocumentToolsProvider>\n <PresentationWindow />\n </ConnectedDocumentToolsProvider>\n )\n}\n\nfunction PresentationWindow() {\n const session = useArbiSessionStore()\n const notify = usePresentation((s) => s.notify)\n const presenting = usePresentation((s) => s.presenting)\n const isOpen = useArbiSessionState((state) => isPanelOpen(state, PRESENTATION_PANEL))\n const { user } = useArbiSession()\n const userId = user?.external_id ?? null\n const shownFor = useRef(userId)\n const { downloadFile } = usePresentationFiles()\n const logoId = usePresentation((s) => s.theme.logo?.documentId ?? null)\n const controller = usePresentationController(isOpen && !presenting)\n\n useEffect(() => {\n if (shownFor.current === userId) return\n shownFor.current = userId\n usePresentation.getState().reset()\n session.closePanel(PRESENTATION_PANEL)\n }, [userId, session])\n\n // The theme's logo image, fetched whenever the logo changes (the theme keeps a reference only).\n useEffect(() => {\n if (!logoId) return\n let current = true\n downloadFile(logoId)\n .then((image) => current && usePresentation.getState().setLogoImage(image))\n .catch(() => current && notify('The logo could not be read', 'error'))\n return () => {\n current = false\n }\n }, [logoId, downloadFile, notify])\n\n // A closed window is not presenting.\n useEffect(() => {\n if (!isOpen) usePresentation.getState().setPresenting(false)\n }, [isOpen])\n\n // Opened only to present: closed when presenting ends (Escape).\n const wasPresenting = useRef(presenting)\n useEffect(() => {\n if (wasPresenting.current && !presenting && isOpen && presentationWindowOnlyPresents()) {\n session.closePanel(PRESENTATION_PANEL)\n }\n wasPresenting.current = presenting\n }, [presenting, isOpen, session])\n\n const onClose = useCallback(() => session.closePanel(PRESENTATION_PANEL), [session])\n\n return (\n <ConnectedPanelHost\n panelId={PRESENTATION_PANEL}\n isOpen={isOpen}\n onClose={onClose}\n title=\"Presentation\"\n defaultMode=\"popout\"\n defaultWidth={960}\n closeTestId=\"presentation-panel-close\"\n >\n {/* Inside the panel, so its dialogs open in its window. */}\n {() => (\n <>\n {!presenting && controller.dialogs}\n <PresenterView\n {...controller.editor}\n actions={\n <>\n {controller.editor.actions}\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"size-8 text-muted-foreground hover:text-foreground pointer-coarse:size-11\"\n title=\"Back into the app's viewer\"\n aria-label=\"Back to the viewer\"\n onClick={onClose}\n data-testid=\"presentation-pop-in\"\n >\n <PanelLeftClose className=\"size-4\" />\n </Button>\n </>\n }\n />\n </>\n )}\n </ConnectedPanelHost>\n )\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkDWMWEALB_cjs = require('./chunk-DWMWEALB.cjs');
|
|
5
5
|
require('./chunk-WOOOMTTA.cjs');
|
|
6
6
|
require('./chunk-5GCCUXMT.cjs');
|
|
7
7
|
require('./chunk-2F57IO7S.cjs');
|
|
@@ -37,6 +37,8 @@ var ui = require('@arbidocs/react/ui');
|
|
|
37
37
|
var jsxRuntime = require('react/jsx-runtime');
|
|
38
38
|
|
|
39
39
|
var listOf = (numbers) => numbers.length < 2 ? String(numbers[0] ?? "") : `${numbers.slice(0, -1).join(", ")} and ${numbers[numbers.length - 1]}`;
|
|
40
|
+
var AUTO_SAVE_AFTER_MS = 2500;
|
|
41
|
+
var DEFAULT_NAMES = /^(new|untitled) presentation( \d+)?$/i;
|
|
40
42
|
var STALE = "This presentation was changed outside the editor: Save to draw its slides again.";
|
|
41
43
|
var hasContent = () => chunk4TTX6ZNS_cjs.hasUnsavedChanges(chunk4TTX6ZNS_cjs.usePresentation.getState());
|
|
42
44
|
function ConnectedSlidesTab({
|
|
@@ -48,7 +50,7 @@ function ConnectedSlidesTab({
|
|
|
48
50
|
const session = react.useArbiSessionStore();
|
|
49
51
|
const { windows, popoutTitle } = chunk2RLA6QO2_cjs.usePanelHostSupport();
|
|
50
52
|
const { confirm } = chunkTKHCIHE2_cjs.useBlocksEnvironment();
|
|
51
|
-
const { open, save } =
|
|
53
|
+
const { open, save } = chunkDWMWEALB_cjs.usePresentationFiles();
|
|
52
54
|
const notify = chunk4TTX6ZNS_cjs.usePresentation((s) => s.notify);
|
|
53
55
|
const boundTo = chunk4TTX6ZNS_cjs.usePresentation((s) => s.boundTo);
|
|
54
56
|
const savedId = chunk4TTX6ZNS_cjs.usePresentation((s) => s.savedId);
|
|
@@ -58,7 +60,7 @@ function ConnectedSlidesTab({
|
|
|
58
60
|
const poppedOut = react.useArbiSessionState(
|
|
59
61
|
(state) => react.isPanelOpen(state, chunkGFUOCGY6_cjs.PRESENTATION_PANEL) && !chunkGFUOCGY6_cjs.presentationWindowOnlyPresents()
|
|
60
62
|
);
|
|
61
|
-
const controller =
|
|
63
|
+
const controller = chunkDWMWEALB_cjs.usePresentationController(!poppedOut);
|
|
62
64
|
const asked = react$1.useRef(null);
|
|
63
65
|
const [declined, setDeclined] = react$1.useState(false);
|
|
64
66
|
const [force, setForce] = react$1.useState(0);
|
|
@@ -152,6 +154,29 @@ function ConnectedSlidesTab({
|
|
|
152
154
|
)
|
|
153
155
|
).finally(() => setLoading(false));
|
|
154
156
|
}, [currentVersion, heldVersion, isDraft, version, loading, open, documentId, target, notify]);
|
|
157
|
+
const draftHasContent = chunk4TTX6ZNS_cjs.usePresentation(
|
|
158
|
+
(state) => isDraft && state.boundTo === target && state.savedId === null && chunk4TTX6ZNS_cjs.hasUnsavedChanges(state)
|
|
159
|
+
);
|
|
160
|
+
const autoSaved = react$1.useRef(null);
|
|
161
|
+
react$1.useEffect(() => {
|
|
162
|
+
if (!draftHasContent || autoSaved.current === target) return;
|
|
163
|
+
const timer = setTimeout(() => {
|
|
164
|
+
autoSaved.current = target;
|
|
165
|
+
const state = chunk4TTX6ZNS_cjs.usePresentation.getState();
|
|
166
|
+
const firstTitle = state.slides.find((slide) => slide.caption.trim())?.caption.trim();
|
|
167
|
+
const named = state.title && !DEFAULT_NAMES.test(state.title) ? state.title : null;
|
|
168
|
+
const title = named ?? firstTitle ?? (state.title || "Untitled presentation");
|
|
169
|
+
if (title !== state.title) state.setTitle(title);
|
|
170
|
+
void save(title).catch((error) => {
|
|
171
|
+
autoSaved.current = null;
|
|
172
|
+
notify(
|
|
173
|
+
error instanceof Error ? error.message : "The presentation could not be saved",
|
|
174
|
+
"error"
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
}, AUTO_SAVE_AFTER_MS);
|
|
178
|
+
return () => clearTimeout(timer);
|
|
179
|
+
}, [draftHasContent, target, save, draftTitle, notify]);
|
|
155
180
|
react$1.useEffect(() => {
|
|
156
181
|
if (isDraft || version || savedId !== documentId || boundTo !== target) return;
|
|
157
182
|
return react.registerDocumentTurnFlush(documentId, async () => {
|
|
@@ -205,23 +230,20 @@ function ConnectedSlidesTab({
|
|
|
205
230
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
206
231
|
controller.dialogs,
|
|
207
232
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
208
|
-
|
|
233
|
+
chunkDWMWEALB_cjs.SlidesEditor,
|
|
209
234
|
{
|
|
210
235
|
...controller.editor,
|
|
211
|
-
|
|
212
|
-
controller.editor.
|
|
213
|
-
/* @__PURE__ */ jsxRuntime.
|
|
214
|
-
ui.
|
|
236
|
+
menuItems: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
237
|
+
controller.editor.menuItems,
|
|
238
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
239
|
+
ui.DropdownMenuItem,
|
|
215
240
|
{
|
|
216
|
-
|
|
217
|
-
size: "icon",
|
|
218
|
-
variant: "ghost",
|
|
219
|
-
className: "size-8 text-muted-foreground hover:text-foreground pointer-coarse:size-11",
|
|
220
|
-
title: "Edit in its own window, beside the documents you clip from",
|
|
221
|
-
"aria-label": "Pop out",
|
|
222
|
-
onClick: () => chunkGFUOCGY6_cjs.openPresentation(session, { windows, title: popoutTitle("Presentation") }),
|
|
241
|
+
onSelect: () => chunkGFUOCGY6_cjs.openPresentation(session, { windows, title: popoutTitle("Presentation") }),
|
|
223
242
|
"data-testid": "presentation-pop-out",
|
|
224
|
-
children:
|
|
243
|
+
children: [
|
|
244
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "size-4" }),
|
|
245
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: "Edit in its own window" })
|
|
246
|
+
]
|
|
225
247
|
}
|
|
226
248
|
)
|
|
227
249
|
] }),
|
|
@@ -232,5 +254,5 @@ function ConnectedSlidesTab({
|
|
|
232
254
|
}
|
|
233
255
|
|
|
234
256
|
exports.ConnectedSlidesTab = ConnectedSlidesTab;
|
|
235
|
-
//# sourceMappingURL=ConnectedSlidesTab-
|
|
236
|
-
//# sourceMappingURL=ConnectedSlidesTab-
|
|
257
|
+
//# sourceMappingURL=ConnectedSlidesTab-7YMEDGUU.cjs.map
|
|
258
|
+
//# sourceMappingURL=ConnectedSlidesTab-7YMEDGUU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connection/presentation/ConnectedSlidesTab.tsx"],"names":["hasUnsavedChanges","usePresentation","useArbiSessionStore","usePanelHostSupport","useBlocksEnvironment","usePresentationFiles","useState","useArbiSessionState","isPanelOpen","PRESENTATION_PANEL","presentationWindowOnlyPresents","usePresentationController","useRef","useEffect","editPresentation","registerDocumentTurnFlush","useCallback","openPresentation","jsx","EmptyState","ExternalLink","jsxs","Button","PanelLeftClose","Presentation","Loader2","Fragment","SlidesEditor","DropdownMenuItem"],"mappings":"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","file":"ConnectedSlidesTab-7YMEDGUU.cjs","sourcesContent":["/**\n * A presentation's slides tab in the document viewer: the slides editor, on the presentation the\n * viewer shows. Opening a saved presentation loads it (unless it is the one being edited); a new\n * one (a presentation draft) takes the clips gathered so far. Clips gathered with no presentation\n * open join the one opened next. Saving a draft makes it a document, and the tab moves to it.\n *\n * The editor can also move to the presentation's own window (Pop out), beside the documents its\n * clips come from; the tab then says so. Present opens that window with the slides alone.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { ExternalLink, Loader2, PanelLeftClose, Presentation } from 'lucide-react'\nimport {\n isPanelOpen,\n registerDocumentTurnFlush,\n useArbiSessionState,\n useArbiSessionStore,\n} from '@arbidocs/react'\nimport { Button, DropdownMenuItem } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { usePanelHostSupport } from '../../shell/panel-host'\nimport {\n PRESENTATION_PANEL,\n openPresentation,\n presentationWindowOnlyPresents,\n} from '../../presentation/panel-id'\nimport { SlidesEditor } from '../../presentation/SlidesEditor'\nimport { hasUnsavedChanges, usePresentation } from '../../presentation/store'\nimport { EmptyState } from '../../components/EmptyState'\nimport { editPresentation } from './requests'\nimport { usePresentationController } from './usePresentationController'\nimport { usePresentationFiles } from './usePresentationFiles'\n\nexport interface ConnectedSlidesTabProps {\n /** The viewed document's id, or a presentation draft's (`draft-…`). */\n documentId: string\n /** The version on screen, when an older one. */\n version?: number\n /** The document's current version: a newer one than the one being edited is opened. */\n currentVersion?: number\n /** A new presentation, not saved yet: its draft title. */\n draftTitle?: string\n}\n\n/** \"2, 3 and 5\". */\nconst listOf = (numbers: number[]) =>\n numbers.length < 2\n ? String(numbers[0] ?? '')\n : `${numbers.slice(0, -1).join(', ')} and ${numbers[numbers.length - 1]}`\n\n/** A new presentation saves itself this long after its first content (typing settles first). */\nconst AUTO_SAVE_AFTER_MS = 2500\n/** The names a new presentation starts with (not chosen by anyone). */\nconst DEFAULT_NAMES = /^(new|untitled) presentation( \\d+)?$/i\n\nconst STALE = 'This presentation was changed outside the editor: Save to draw its slides again.'\n\n/** The presentation has anything in it worth asking about before it is replaced. */\nconst hasContent = () => hasUnsavedChanges(usePresentation.getState())\n\nexport function ConnectedSlidesTab({\n documentId,\n version,\n currentVersion,\n draftTitle,\n}: ConnectedSlidesTabProps) {\n const session = useArbiSessionStore()\n const { windows, popoutTitle } = usePanelHostSupport()\n const { confirm } = useBlocksEnvironment()\n const { open, save } = usePresentationFiles()\n const notify = usePresentation((s) => s.notify)\n const boundTo = usePresentation((s) => s.boundTo)\n const savedId = usePresentation((s) => s.savedId)\n const [loading, setLoading] = useState(false)\n const isDraft = draftTitle !== undefined\n const target = version ? `${documentId}@v${version}` : documentId\n const poppedOut = useArbiSessionState(\n (state) => isPanelOpen(state, PRESENTATION_PANEL) && !presentationWindowOnlyPresents()\n )\n const controller = usePresentationController(!poppedOut)\n const asked = useRef<string | null>(null)\n // Another presentation, with changes, is being edited and the user kept it.\n const [declined, setDeclined] = useState(false)\n const [force, setForce] = useState(0)\n\n // Show the presentation this tab is for (once per presentation: a remount does not ask again).\n useEffect(() => {\n const state = usePresentation.getState()\n if (state.boundTo === target || asked.current === `${target}#${force}`) return\n asked.current = `${target}#${force}`\n setDeclined(false)\n void (async () => {\n // Clips gathered with no presentation open join this one.\n const gathered = state.boundTo === null ? state.clips : []\n if (state.boundTo !== null && hasContent() && !force) {\n const ok = await confirm({\n title: 'Open presentation',\n message: 'Replace the presentation being edited? Save it first to keep its changes.',\n kind: 'confirm',\n })\n if (!ok) return setDeclined(true)\n }\n if (isDraft) {\n if (state.boundTo !== null) state.reset()\n usePresentation.getState().bind(target)\n usePresentation.getState().setTitle(draftTitle || 'Untitled presentation')\n return\n }\n setLoading(true)\n try {\n const { missing, stale, imported, changedOutside } = await open(documentId, version)\n usePresentation.getState().bind(target)\n if (gathered.length) usePresentation.getState().adoptClips(gathered)\n if (stale) notify(STALE, 'error')\n if (imported) {\n notify(\n ['Opened from PowerPoint, ready to edit.', ...imported.notes].join(' · '),\n 'success'\n )\n }\n if (changedOutside) {\n notify(\n `${changedOutside.length === 1 ? `Slide ${changedOutside[0]} was` : `Slides ${listOf(changedOutside)} were`} changed in PowerPoint: brought in as changed there.`,\n 'success'\n )\n }\n if (missing) {\n notify(\n `${missing} clip${missing === 1 ? '' : 's'} could not be opened (moved, deleted or not shared with you)`,\n 'error'\n )\n }\n } catch (error) {\n notify(\n error instanceof Error ? error.message : 'The presentation could not be opened',\n 'error'\n )\n } finally {\n setLoading(false)\n }\n })()\n // eslint-disable-next-line react-hooks/exhaustive-deps -- a draft's title changes as it is typed\n }, [target, documentId, version, isDraft, force, open, confirm, notify])\n\n // A draft's title is the presentation's.\n useEffect(() => {\n if (isDraft && boundTo === target && draftTitle) usePresentation.getState().setTitle(draftTitle)\n }, [isDraft, boundTo, target, draftTitle])\n\n // Saved as another document (a draft's first save, Save as, an older file saved as a\n // PowerPoint): the viewer follows it. Only once this tab's presentation was the one edited\n // (another, still bound as the tab opens, is not \"its\" save).\n const wasBound = useRef(false)\n useEffect(() => {\n if (boundTo === target) wasBound.current = true\n if (!wasBound.current || !savedId || boundTo !== savedId || savedId === target) return\n if (isDraft) session.clearDraftDocument(documentId)\n editPresentation(session, { kind: 'open', documentId: savedId })\n }, [isDraft, savedId, boundTo, target, documentId, session])\n\n // A newer version saved meanwhile (by ARBI, asked in the chat beside the deck, or by someone\n // else): shown at once, unless this one has changes of its own, which are never thrown away.\n const heldVersion = usePresentation((s) => (s.boundTo === target ? s.version : null))\n const toldNewer = useRef<number | null>(null)\n useEffect(() => {\n if (isDraft || version || !currentVersion || heldVersion === null) return\n if (currentVersion <= heldVersion || loading) return\n if (hasContent()) {\n if (toldNewer.current === currentVersion) return\n toldNewer.current = currentVersion\n notify(\n `A newer version (${currentVersion}) was saved while you edited. Save as… keeps yours; reopen the presentation to see it.`,\n 'error'\n )\n return\n }\n setLoading(true)\n void open(documentId)\n .then(() => {\n usePresentation.getState().bind(target)\n notify(`Updated to version ${currentVersion}.`, 'success')\n })\n .catch((error: unknown) =>\n notify(\n error instanceof Error ? error.message : 'The new version could not be opened',\n 'error'\n )\n )\n .finally(() => setLoading(false))\n }, [currentVersion, heldVersion, isDraft, version, loading, open, documentId, target, notify])\n\n // A new presentation saves itself once it has something in it (a clip, a title, a point): from\n // then on it is a document of Presentations, which a chat can work in and look at (its PDF), and\n // which is not lost with the tab. Later saves stay the person's (each a version they chose).\n const draftHasContent = usePresentation(\n (state) =>\n isDraft && state.boundTo === target && state.savedId === null && hasUnsavedChanges(state)\n )\n const autoSaved = useRef<string | null>(null)\n useEffect(() => {\n if (!draftHasContent || autoSaved.current === target) return\n const timer = setTimeout(() => {\n autoSaved.current = target\n const state = usePresentation.getState()\n // Still called what every new one is called: named after its first slide's title instead.\n const firstTitle = state.slides.find((slide) => slide.caption.trim())?.caption.trim()\n const named = state.title && !DEFAULT_NAMES.test(state.title) ? state.title : null\n const title = named ?? firstTitle ?? (state.title || 'Untitled presentation')\n if (title !== state.title) state.setTitle(title)\n void save(title).catch((error: unknown) => {\n autoSaved.current = null\n notify(\n error instanceof Error ? error.message : 'The presentation could not be saved',\n 'error'\n )\n })\n }, AUTO_SAVE_AFTER_MS)\n return () => clearTimeout(timer)\n }, [draftHasContent, target, save, draftTitle, notify])\n\n // A chat turn about this presentation (the chat beside it) saves its unsaved changes first, so\n // ARBI works on the slides as they are on screen.\n useEffect(() => {\n if (isDraft || version || savedId !== documentId || boundTo !== target) return\n return registerDocumentTurnFlush(documentId, async () => {\n const state = usePresentation.getState()\n if (state.savedId === documentId && hasUnsavedChanges(state)) await save(state.title)\n })\n }, [isDraft, version, savedId, boundTo, documentId, target, save])\n\n const present = useCallback(() => {\n openPresentation(session, { present: true, windows, title: popoutTitle('Presentation') })\n usePresentation.getState().setPresenting(true)\n }, [session, windows, popoutTitle])\n\n if (poppedOut) {\n return (\n <div className=\"flex h-full items-center justify-center p-6\" data-testid=\"slides-popped-out\">\n <EmptyState\n icon={ExternalLink}\n title=\"Editing in its own window\"\n description=\"The presentation is open in its own window, beside the documents you clip from.\"\n action={\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => session.closePanel(PRESENTATION_PANEL)}\n >\n <PanelLeftClose className=\"size-4\" />\n Bring it back here\n </Button>\n }\n />\n </div>\n )\n }\n if (declined && boundTo !== target) {\n return (\n <div className=\"flex h-full items-center justify-center p-6\" data-testid=\"slides-declined\">\n <EmptyState\n icon={Presentation}\n title=\"Another presentation is being edited\"\n description=\"It has changes. Save it first, or open this one in its place.\"\n action={\n <Button type=\"button\" variant=\"outline\" onClick={() => setForce((n) => n + 1)}>\n Open this one instead\n </Button>\n }\n />\n </div>\n )\n }\n if (loading || boundTo !== target) {\n return (\n <div className=\"flex h-full items-center justify-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"size-4 animate-spin\" />\n Opening the presentation…\n </div>\n )\n }\n return (\n <>\n {controller.dialogs}\n <SlidesEditor\n {...controller.editor}\n menuItems={\n <>\n {controller.editor.menuItems}\n <DropdownMenuItem\n onSelect={() =>\n openPresentation(session, { windows, title: popoutTitle('Presentation') })\n }\n data-testid=\"presentation-pop-out\"\n >\n <ExternalLink className=\"size-4\" />\n <span className=\"ml-2\">Edit in its own window</span>\n </DropdownMenuItem>\n </>\n }\n onPresent={present}\n />\n </>\n )\n}\n"]}
|
|
@@ -21,9 +21,9 @@ require('./chunk-3YEXZX4H.cjs');
|
|
|
21
21
|
require('./chunk-4PA6VCCR.cjs');
|
|
22
22
|
require('./chunk-WXUU3COI.cjs');
|
|
23
23
|
require('./chunk-AHDJXIUB.cjs');
|
|
24
|
+
require('./chunk-YVCOQHCE.cjs');
|
|
24
25
|
require('./chunk-RL2HI6NP.cjs');
|
|
25
26
|
require('./chunk-6UZC4XVV.cjs');
|
|
26
|
-
require('./chunk-YVCOQHCE.cjs');
|
|
27
27
|
require('./chunk-JV5TVUOU.cjs');
|
|
28
28
|
require('./chunk-ZVEW3JBT.cjs');
|
|
29
29
|
require('./chunk-VZOOGA47.cjs');
|
|
@@ -5,7 +5,7 @@ var chunkVWBYE3XY_cjs = require('./chunk-VWBYE3XY.cjs');
|
|
|
5
5
|
require('./chunk-XF355M7O.cjs');
|
|
6
6
|
require('./chunk-2F57IO7S.cjs');
|
|
7
7
|
require('./chunk-UFT22LAB.cjs');
|
|
8
|
-
var
|
|
8
|
+
var chunkJD2HX2BR_cjs = require('./chunk-JD2HX2BR.cjs');
|
|
9
9
|
require('./chunk-WFMWKPGY.cjs');
|
|
10
10
|
require('./chunk-4TTX6ZNS.cjs');
|
|
11
11
|
require('./chunk-4CIVQWAX.cjs');
|
|
@@ -24,7 +24,7 @@ require('./chunk-4ONPEVTP.cjs');
|
|
|
24
24
|
require('./chunk-V3KLUWQQ.cjs');
|
|
25
25
|
require('./chunk-P5AQYC4D.cjs');
|
|
26
26
|
require('./chunk-WAV762GP.cjs');
|
|
27
|
-
require('./chunk-
|
|
27
|
+
require('./chunk-46P7IDBX.cjs');
|
|
28
28
|
require('./chunk-GNZAH6UI.cjs');
|
|
29
29
|
require('./chunk-JH6JTI76.cjs');
|
|
30
30
|
require('./chunk-QQMMCXBP.cjs');
|
|
@@ -43,9 +43,9 @@ require('./chunk-WQMR3O2D.cjs');
|
|
|
43
43
|
require('./chunk-ORELHENJ.cjs');
|
|
44
44
|
require('./chunk-NWNVWO6L.cjs');
|
|
45
45
|
require('./chunk-SK6HQ46Q.cjs');
|
|
46
|
+
require('./chunk-TG2GM7WJ.cjs');
|
|
46
47
|
require('./chunk-MNIQDXM6.cjs');
|
|
47
48
|
require('./chunk-E3Y7RI3J.cjs');
|
|
48
|
-
require('./chunk-TG2GM7WJ.cjs');
|
|
49
49
|
require('./chunk-VKH3BEZE.cjs');
|
|
50
50
|
require('./chunk-OEJQFPWO.cjs');
|
|
51
51
|
require('./chunk-7JLJH5CW.cjs');
|
|
@@ -58,9 +58,9 @@ require('./chunk-3YEXZX4H.cjs');
|
|
|
58
58
|
require('./chunk-4PA6VCCR.cjs');
|
|
59
59
|
require('./chunk-WXUU3COI.cjs');
|
|
60
60
|
require('./chunk-AHDJXIUB.cjs');
|
|
61
|
+
require('./chunk-YVCOQHCE.cjs');
|
|
61
62
|
require('./chunk-RL2HI6NP.cjs');
|
|
62
63
|
require('./chunk-6UZC4XVV.cjs');
|
|
63
|
-
require('./chunk-YVCOQHCE.cjs');
|
|
64
64
|
require('./chunk-JV5TVUOU.cjs');
|
|
65
65
|
require('./chunk-ZVEW3JBT.cjs');
|
|
66
66
|
require('./chunk-EG7EJFUE.cjs');
|
|
@@ -231,11 +231,11 @@ function FilesViewerDialog({ artifactRuntimeUrl, ...props }) {
|
|
|
231
231
|
DocumentViewerDialog,
|
|
232
232
|
{
|
|
233
233
|
...props,
|
|
234
|
-
renderDocument: (id) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
234
|
+
renderDocument: (id) => /* @__PURE__ */ jsxRuntime.jsx(chunkJD2HX2BR_cjs.ConnectedDocumentViewer, { documentId: id, artifactRuntimeUrl })
|
|
235
235
|
}
|
|
236
236
|
);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
exports.FilesViewerDialog = FilesViewerDialog;
|
|
240
|
-
//# sourceMappingURL=FilesViewerDialog-
|
|
241
|
-
//# sourceMappingURL=FilesViewerDialog-
|
|
240
|
+
//# sourceMappingURL=FilesViewerDialog-2QCCRWF2.cjs.map
|
|
241
|
+
//# sourceMappingURL=FilesViewerDialog-2QCCRWF2.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/connection/viewer/DocumentViewerDialog.tsx","../src/connection/files/page/FilesViewerDialog.tsx"],"names":["jsx","Eye","PenLine","MessageSquareText","DEFAULT_DOCUMENT_VIEWER_TABS","DEFAULT_ASK_SUGGESTIONS","DEFAULT_DOCUMENT_VIEWER_LABELS","useConnectedWorkspace","useArbiSessionStore","useBlocksEnvironment","useArbiSessionState","useDocuments","parseVersionRef","tab","useState","question","useRef","useSlashField","Dialog","jsxs","DialogContent","DialogHeader","DialogTitle","FileText","DialogDescription","SegmentedControl","ErrorBoundary","DocumentReview","AskBar","ConnectedDocumentViewer"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,IAAM,UAAU,CAAC,GAAA,KACf,KAAK,YAAA,EAAc,KAAA,IAAS,KAAK,SAAA,IAAa,UAAA;AAEhD,IAAM,SAAA,GAAkD;AAAA,EACtD,MAAA,kBAAQA,cAAA,CAACC,eAAA,EAAA,EAAI,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,EAChC,QAAA,kBAAUD,cAAA,CAACE,mBAAA,EAAA,EAAQ,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,EACtC,GAAA,kBAAKF,cAAA,CAACG,6BAAA,EAAA,EAAkB,SAAA,EAAU,QAAA,EAAS;AAC7C,CAAA;AAEA,IAAM,YAAA,GAAkD;AAAA,EACtD,MAAA,EAAQ,mBAAA;AAAA,EACR,QAAA,EAAU,gBAAA;AAAA,EACV,GAAA,EAAK;AACP,CAAA;AAEO,SAAS,oBAAA,CAAqB;AAAA,EACnC,UAAA;AAAA,EACA,IAAA,GAAOC,8CAAA;AAAA,EACP,UAAA;AAAA,EACA,MAAA,EAAQ,cAAA;AAAA,EACR,cAAA,GAAiBC,yCAAA;AAAA,EACjB,OAAA;AAAA,EACA;AACF,CAAA,EAA8B;AAC5B,EAAA,MAAM,MAAA,GAAS,EAAE,GAAGC,gDAAA,EAAgC,GAAG,cAAA,EAAe;AACtE,EAAA,MAAM,EAAE,WAAA,EAAa,IAAA,EAAK,GAAIC,uCAAA,EAAsB;AACpD,EAAA,MAAM,UAAUC,yBAAA,EAAoB;AACpC,EAAA,MAAM,EAAE,mBAAA,EAAoB,GAAIC,sCAAA,EAAqB;AACrD,EAAA,MAAM,YAAYC,yBAAA,CAAoB,CAAC,MAAM,CAAA,CAAE,eAAA,EAAiB,aAAa,IAAI,CAAA;AACjF,EAAA,MAAM,QAAQA,yBAAA,CAAoB,CAAC,MAAM,CAAA,CAAE,cAAA,CAAe,UAAU,CAAC,CAAA;AACrE,EAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAU,GAAIC,kBAAA,EAAa;AACzC,EAAA,MAAM,MAAA,GAASC,yBAAA,CAAgB,UAAU,CAAA,CAAE,KAAA;AAC3C,EAAA,MAAM,MAAM,SAAA,EAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAgB,MAAM,CAAA;AAC3D,EAAA,MAAM,KAAA,GAAQ,KAAA,EAAO,KAAA,IAAS,OAAA,CAAQ,GAAG,CAAA;AAIzC,EAAA,MAAM,OAAA,GAAwC,KAAA,GAC1C,CAAC,UAAU,CAAA,GACX,IAAA,CAAK,MAAA,CAAO,CAACC,IAAAA,KAAQA,IAAAA,KAAQ,UAAA,IAAc,IAAI,CAAA;AACnD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,iBAAwC,UAAU,CAAA;AAC9E,EAAA,MAAM,GAAA,GAAM,UAAU,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,GAAI,MAAA,GAAS,QAAQ,CAAC,CAAA;AAEnE,EAAA,MAAM,OAAA,GAAgD,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,IAC5E,KAAA;AAAA,IACA,KAAA,EAAO,OAAO,KAAK,CAAA;AAAA,IACnB,IAAA,EAAM,UAAU,KAAK,CAAA;AAAA,IACrB,MAAA,EAAQ,aAAa,KAAK;AAAA,GAC5B,CAAE,CAAA;AAGF,EAAA,MAAM,GAAA,GAAM,CAACC,SAAAA,KAAqB;AAChC,IAAA,mBAAA,CAAoB,EAAE,MAAA,EAAQA,SAAAA,EAAU,CAAA;AACxC,IAAA,OAAA,CAAQ,qBAAqB,MAAM,CAAA;AAAA,EACrC,CAAA;AAEA,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAID,iBAAS,EAAE,CAAA;AAC3C,EAAA,MAAM,WAAA,GAAcE,eAAyB,IAAI,CAAA;AACjD,EAAA,MAAM,QAAQC,+BAAA,CAAc;AAAA,IAC1B,IAAA,EAAM,QAAA;AAAA,IACN,OAAA,EAAS,WAAA;AAAA,IACT,QAAA,EAAU,WAAA;AAAA,IACV,OAAA,EAAS,MAAA;AAAA,IACT,IAAA,EAAM;AAAA,GACP,CAAA;AAED,EAAA,uBACEjB,cAAA,CAACkB,SAAA,EAAA,EAAO,IAAA,EAAI,IAAA,EAAC,YAAA,EAAc,CAAC,IAAA,KAAS,CAAC,IAAA,IAAQ,OAAA,EAAQ,EACpD,QAAA,kBAAAC,eAAA;AAAA,IAACC,gBAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,+DAAA;AAAA,MACV,aAAA,EAAY,kBAAA;AAAA,MAEZ,QAAA,EAAA;AAAA,wBAAAD,eAAA,CAACE,eAAA,EAAA,EAAa,WAAU,oBAAA,EACtB,QAAA,EAAA;AAAA,0BAAAF,eAAA,CAACG,cAAA,EAAA,EAAY,WAAU,gDAAA,EACrB,QAAA,EAAA;AAAA,4BAAAtB,cAAA,CAACuB,oBAAA,EAAA,EAAS,WAAU,iBAAA,EAAkB,CAAA;AAAA,2CACrC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAW,aAAA,EAAY,0BACpC,QAAA,EAAA,KAAA,EACH;AAAA,WAAA,EACF,CAAA;AAAA,0BACAJ,eAAA,CAACK,oBAAA,EAAA,EAAkB,SAAA,EAAU,SAAA,EAC1B,QAAA,EAAA;AAAA,YAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,KAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,YAAE,IAAA;AAAA,YAAG;AAAA,WAAA,EACvD,CAAA;AAAA,UACC,OAAA,CAAQ,MAAA,GAAS,CAAA,IAAK,GAAA,oBACrBxB,cAAA;AAAA,YAACyB,kCAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,eAAA;AAAA,cAEV,SAAA,EAAU,6FAAA;AAAA,cACV,KAAA,EAAO,GAAA;AAAA,cACP,QAAA,EAAU,SAAA;AAAA,cACV;AAAA;AAAA;AACF,SAAA,EAEJ,CAAA;AAAA,wBACAzB,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EAEb,QAAA,kBAAAmB,eAAA;AAAA,UAACO,+BAAA;AAAA,UAAA;AAAA,YACC,QAAA,EAAU,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA;AAAA,YAC9B,MAAA,EAAQ,EAAE,KAAA,EAAO,qCAAA,EAAsC;AAAA,YACvD,MAAA,EAAO,wBAAA;AAAA,YAEN,QAAA,EAAA;AAAA,cAAA,GAAA,KAAQ,QAAA,oBACP1B,cAAA;AAAA,gBAAC2B,oBAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAO,MAAA;AAAA,kBACP,GAAA;AAAA,kBACA,aAAa,WAAA,IAAe,MAAA;AAAA,kBAC5B,aAAA,EAAe;AAAA;AAAA,eACjB;AAAA,cAED,GAAA,KAAQ,UAAA,oBACP3B,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAyB,aAAA,EAAY,yBAAA,EACjD,QAAA,EAAA,cAAA,CAAe,UAAU,CAAA,EAC5B,CAAA;AAAA,cAED,QAAQ,KAAA,oBACPmB,eAAA,CAAC,SAAI,SAAA,EAAU,kCAAA,EAAmC,eAAY,cAAA,EAC5D,QAAA,EAAA;AAAA,gCAAAnB,cAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,+BAAA,EAAiC,QAAA,EAAA,MAAA,CAAO,QAAA,EAAS,CAAA;AAAA,gBAC7D,KAAA,CAAM,QAAA;AAAA,gCACPA,cAAA;AAAA,kBAAC4B,wBAAA;AAAA,kBAAA;AAAA,oBACC,MAAA,EAAO,SAAA;AAAA,oBACP,WAAA,EAAa,MAAA,CAAO,cAAA,CAAe,OAAA,CAAQ,WAAW,KAAK,CAAA;AAAA,oBAC3D,WAAA,EAAa,CAAC,GAAG,cAAc,CAAA;AAAA,oBAC/B,KAAA,EAAO,CAAC,IAAA,KAAS;AACf,sBAAA,IAAI,CAAC,KAAA,CAAM,WAAA,CAAY,IAAI,CAAA,MAAO,IAAI,CAAA;AAAA,oBACxC,CAAA;AAAA,oBACA,KAAA,EAAO,QAAA;AAAA,oBACP,aAAA,EAAe,WAAA;AAAA,oBACf,gBAAgB,KAAA,CAAM,SAAA;AAAA,oBACtB,YAAY,KAAA,CAAM,aAAA;AAAA,oBAClB,QAAA,EAAU,WAAA;AAAA,oBACV,MAAM,KAAA,CAAM;AAAA;AAAA;AACd,eAAA,EACF;AAAA;AAAA;AAAA,SAEJ,EACF;AAAA;AAAA;AAAA,GACF,EACF,CAAA;AAEJ;ACnLO,SAAS,iBAAA,CAAkB,EAAE,kBAAA,EAAoB,GAAG,OAAM,EAA2B;AAC1F,EAAA,uBACE5B,cAAAA;AAAA,IAAC,oBAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,cAAA,EAAgB,CAAC,EAAA,qBACfA,eAAC6B,yCAAA,EAAA,EAAwB,UAAA,EAAY,IAAI,kBAAA,EAAwC;AAAA;AAAA,GAErF;AAEJ","file":"FilesViewerDialog-4352KIOG.cjs","sourcesContent":["/**\n * The document viewer as a dialog (the files page's own viewer): a title, the tabs\n * the host offers, and under them the review (`DocumentReview`), the whole viewer, or a question\n * (`AskBar`) that starts a thread about the document. Views of existing parts, not a new viewer.\n *\n * A draft started with Create New (the session's `draftDocuments`) has no server record yet: it\n * shows the whole viewer only (its kind, name and recorder), titled from the draft.\n */\n\nimport { useRef, useState, type ReactNode } from 'react'\nimport { Eye, FileText, MessageSquareText, PenLine } from 'lucide-react'\nimport {\n DocumentReview,\n useArbiSessionState,\n useArbiSessionStore,\n useDocuments,\n type WorkspaceDocument,\n} from '@arbidocs/react'\nimport { parseVersionRef } from '@arbidocs/react/artifacts'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@arbidocs/react/ui'\nimport { AskBar } from '../../components/AskBar'\nimport { ErrorBoundary } from '../../components/ErrorBoundary'\nimport { SegmentedControl, type SegmentedOption } from '../../settings/SegmentedControl'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { useConnectedWorkspace } from '../ConnectionProvider'\nimport { useSlashField } from '../ask/useSlashField'\nimport {\n DEFAULT_ASK_SUGGESTIONS,\n DEFAULT_DOCUMENT_VIEWER_LABELS,\n DEFAULT_DOCUMENT_VIEWER_TABS,\n type DocumentViewerDialogLabels,\n type DocumentViewerTab,\n} from './documentViewerTabs'\n\ntype ReviewDocument = Parameters<typeof DocumentReview>[0]['doc']\n\nexport interface DocumentViewerDialogProps {\n /** The document, or a version reference `doc-…@v{n}`. */\n documentId: string\n /** The views offered, in order. Default: review, document, ask. */\n tabs?: readonly DocumentViewerTab[]\n /** The view it opens on. Default: the first offered. */\n initialTab?: DocumentViewerTab\n labels?: DocumentViewerDialogLabels\n /** The ask view's suggested questions. */\n askSuggestions?: readonly string[]\n onClose: () => void\n /** The whole viewer, for the document view. */\n renderDocument: (documentId: string) => ReactNode\n}\n\nconst titleOf = (doc: WorkspaceDocument | undefined) =>\n doc?.doc_metadata?.title || doc?.file_name || 'Document'\n\nconst TAB_ICONS: Record<DocumentViewerTab, ReactNode> = {\n review: <Eye className=\"size-4\" />,\n document: <PenLine className=\"size-4\" />,\n ask: <MessageSquareText className=\"size-4\" />,\n}\n\nconst TAB_TEST_IDS: Record<DocumentViewerTab, string> = {\n review: 'review-tab-review',\n document: 'review-tab-pdf',\n ask: 'review-tab-qa',\n}\n\nexport function DocumentViewerDialog({\n documentId,\n tabs = DEFAULT_DOCUMENT_VIEWER_TABS,\n initialTab,\n labels: labelOverrides,\n askSuggestions = DEFAULT_ASK_SUGGESTIONS,\n onClose,\n renderDocument,\n}: DocumentViewerDialogProps) {\n const labels = { ...DEFAULT_DOCUMENT_VIEWER_LABELS, ...labelOverrides }\n const { workspaceId, live } = useConnectedWorkspace()\n const session = useArbiSessionStore()\n const { openNewConversation } = useBlocksEnvironment()\n const passageId = useArbiSessionState((s) => s.viewingDocument?.passageId ?? null)\n const draft = useArbiSessionState((s) => s.draftDocuments[documentId])\n const { data: documents } = useDocuments()\n const baseId = parseVersionRef(documentId).docId\n const doc = documents?.find((d) => d.external_id === baseId)\n const title = draft?.title || titleOf(doc)\n\n // The whole viewer needs a signed-in session (marking up, signing, versions). A draft is only\n // on the client: there is nothing to review or ask about until it is saved.\n const offered: readonly DocumentViewerTab[] = draft\n ? ['document']\n : tabs.filter((tab) => tab !== 'document' || live)\n const [chosen, setChosen] = useState<DocumentViewerTab | undefined>(initialTab)\n const tab = chosen && offered.includes(chosen) ? chosen : offered[0]\n\n const options: SegmentedOption<DocumentViewerTab>[] = offered.map((value) => ({\n value,\n label: labels[value],\n icon: TAB_ICONS[value],\n testId: TAB_TEST_IDS[value],\n }))\n\n // A question opens a new thread about the document, as the viewer's \"Chat\" does.\n const ask = (question: string) => {\n openNewConversation({ prompt: question })\n session.setNewChatDocumentId(baseId)\n }\n // The `/` menu: a skill's run is asked the same way, so its thread is about this document too.\n const [question, setQuestion] = useState('')\n const askInputRef = useRef<HTMLInputElement>(null)\n const slash = useSlashField({\n text: question,\n setText: setQuestion,\n inputRef: askInputRef,\n landing: 'chat',\n send: ask,\n })\n\n return (\n <Dialog open onOpenChange={(open) => !open && onClose()}>\n <DialogContent\n className=\"flex h-[90vh] max-w-[95vw] flex-col gap-0 p-0 sm:max-w-[95vw]\"\n data-testid=\"documents-dialog\"\n >\n <DialogHeader className=\"border-b px-4 py-3\">\n <DialogTitle className=\"flex min-w-0 items-center gap-2 pr-8 text-base\">\n <FileText className=\"size-4 shrink-0\" />\n <span className=\"truncate\" data-testid=\"documents-dialog-title\">\n {title}\n </span>\n </DialogTitle>\n <DialogDescription className=\"sr-only\">\n {offered.map((value) => labels[value]).join(', ')}: {title}\n </DialogDescription>\n {options.length > 1 && tab && (\n <SegmentedControl\n ariaLabel=\"Document view\"\n // A phone fits the three on one row: no label breaks over two lines.\n className=\"mt-2 w-fit max-w-full overflow-x-auto [&_button]:whitespace-nowrap max-sm:[&_button]:px-2.5\"\n value={tab}\n onChange={setChosen}\n options={options}\n />\n )}\n </DialogHeader>\n <div className=\"min-h-0 flex-1 overflow-hidden p-3\">\n {/* A view that fails to render says so here: the dialog and the page under it stay. */}\n <ErrorBoundary\n resetKey={`${documentId}|${tab}`}\n labels={{ title: \"This document couldn't be displayed\" }}\n testId=\"documents-dialog-error\"\n >\n {tab === 'review' && (\n <DocumentReview\n docId={baseId}\n doc={doc as ReviewDocument}\n workspaceId={workspaceId ?? undefined}\n activeChunkId={passageId}\n />\n )}\n {tab === 'document' && (\n <div className=\"h-full overflow-hidden\" data-testid=\"documents-dialog-viewer\">\n {renderDocument(documentId)}\n </div>\n )}\n {tab === 'ask' && (\n <div className=\"mx-auto max-w-2xl space-y-3 pt-6\" data-testid=\"doc-qa-panel\">\n <p className=\"text-sm text-muted-foreground\">{labels.askIntro}</p>\n {slash.launcher}\n <AskBar\n testId=\"doc-ask\"\n placeholder={labels.askPlaceholder.replace('{title}', title)}\n suggestions={[...askSuggestions]}\n onAsk={(text) => {\n if (!slash.startsSkill(text)) ask(text)\n }}\n value={question}\n onValueChange={setQuestion}\n onInputKeyDown={slash.onKeyDown}\n inputProps={slash.comboboxProps}\n inputRef={askInputRef}\n menu={slash.menu}\n />\n </div>\n )}\n </ErrorBoundary>\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n","/**\n * The files page's own viewer (a page without a host viewer): `DocumentViewerDialog`, with the\n * whole `ConnectedDocumentViewer` as its document view. The page lazy-loads this module, so the\n * viewer stays out of the page's chunk.\n */\nimport { ConnectedDocumentViewer } from '../../viewer/ConnectedDocumentViewer'\nimport {\n DocumentViewerDialog,\n type DocumentViewerDialogProps,\n} from '../../viewer/DocumentViewerDialog'\n\nexport interface FilesViewerDialogProps extends Omit<DocumentViewerDialogProps, 'renderDocument'> {\n /** Where html/react artifacts load their sandbox runtime from. */\n artifactRuntimeUrl?: string\n}\n\nexport function FilesViewerDialog({ artifactRuntimeUrl, ...props }: FilesViewerDialogProps) {\n return (\n <DocumentViewerDialog\n {...props}\n renderDocument={(id) => (\n <ConnectedDocumentViewer documentId={id} artifactRuntimeUrl={artifactRuntimeUrl} />\n )}\n />\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/connection/viewer/DocumentViewerDialog.tsx","../src/connection/files/page/FilesViewerDialog.tsx"],"names":["jsx","Eye","PenLine","MessageSquareText","DEFAULT_DOCUMENT_VIEWER_TABS","DEFAULT_ASK_SUGGESTIONS","DEFAULT_DOCUMENT_VIEWER_LABELS","useConnectedWorkspace","useArbiSessionStore","useBlocksEnvironment","useArbiSessionState","useDocuments","parseVersionRef","tab","useState","question","useRef","useSlashField","Dialog","jsxs","DialogContent","DialogHeader","DialogTitle","FileText","DialogDescription","SegmentedControl","ErrorBoundary","DocumentReview","AskBar","ConnectedDocumentViewer"],"mappings":"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","file":"FilesViewerDialog-2QCCRWF2.cjs","sourcesContent":["/**\n * The document viewer as a dialog (the files page's own viewer): a title, the tabs\n * the host offers, and under them the review (`DocumentReview`), the whole viewer, or a question\n * (`AskBar`) that starts a thread about the document. Views of existing parts, not a new viewer.\n *\n * A draft started with Create New (the session's `draftDocuments`) has no server record yet: it\n * shows the whole viewer only (its kind, name and recorder), titled from the draft.\n */\n\nimport { useRef, useState, type ReactNode } from 'react'\nimport { Eye, FileText, MessageSquareText, PenLine } from 'lucide-react'\nimport {\n DocumentReview,\n useArbiSessionState,\n useArbiSessionStore,\n useDocuments,\n type WorkspaceDocument,\n} from '@arbidocs/react'\nimport { parseVersionRef } from '@arbidocs/react/artifacts'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '@arbidocs/react/ui'\nimport { AskBar } from '../../components/AskBar'\nimport { ErrorBoundary } from '../../components/ErrorBoundary'\nimport { SegmentedControl, type SegmentedOption } from '../../settings/SegmentedControl'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { useConnectedWorkspace } from '../ConnectionProvider'\nimport { useSlashField } from '../ask/useSlashField'\nimport {\n DEFAULT_ASK_SUGGESTIONS,\n DEFAULT_DOCUMENT_VIEWER_LABELS,\n DEFAULT_DOCUMENT_VIEWER_TABS,\n type DocumentViewerDialogLabels,\n type DocumentViewerTab,\n} from './documentViewerTabs'\n\ntype ReviewDocument = Parameters<typeof DocumentReview>[0]['doc']\n\nexport interface DocumentViewerDialogProps {\n /** The document, or a version reference `doc-…@v{n}`. */\n documentId: string\n /** The views offered, in order. Default: review, document, ask. */\n tabs?: readonly DocumentViewerTab[]\n /** The view it opens on. Default: the first offered. */\n initialTab?: DocumentViewerTab\n labels?: DocumentViewerDialogLabels\n /** The ask view's suggested questions. */\n askSuggestions?: readonly string[]\n onClose: () => void\n /** The whole viewer, for the document view. */\n renderDocument: (documentId: string) => ReactNode\n}\n\nconst titleOf = (doc: WorkspaceDocument | undefined) =>\n doc?.doc_metadata?.title || doc?.file_name || 'Document'\n\nconst TAB_ICONS: Record<DocumentViewerTab, ReactNode> = {\n review: <Eye className=\"size-4\" />,\n document: <PenLine className=\"size-4\" />,\n ask: <MessageSquareText className=\"size-4\" />,\n}\n\nconst TAB_TEST_IDS: Record<DocumentViewerTab, string> = {\n review: 'review-tab-review',\n document: 'review-tab-pdf',\n ask: 'review-tab-qa',\n}\n\nexport function DocumentViewerDialog({\n documentId,\n tabs = DEFAULT_DOCUMENT_VIEWER_TABS,\n initialTab,\n labels: labelOverrides,\n askSuggestions = DEFAULT_ASK_SUGGESTIONS,\n onClose,\n renderDocument,\n}: DocumentViewerDialogProps) {\n const labels = { ...DEFAULT_DOCUMENT_VIEWER_LABELS, ...labelOverrides }\n const { workspaceId, live } = useConnectedWorkspace()\n const session = useArbiSessionStore()\n const { openNewConversation } = useBlocksEnvironment()\n const passageId = useArbiSessionState((s) => s.viewingDocument?.passageId ?? null)\n const draft = useArbiSessionState((s) => s.draftDocuments[documentId])\n const { data: documents } = useDocuments()\n const baseId = parseVersionRef(documentId).docId\n const doc = documents?.find((d) => d.external_id === baseId)\n const title = draft?.title || titleOf(doc)\n\n // The whole viewer needs a signed-in session (marking up, signing, versions). A draft is only\n // on the client: there is nothing to review or ask about until it is saved.\n const offered: readonly DocumentViewerTab[] = draft\n ? ['document']\n : tabs.filter((tab) => tab !== 'document' || live)\n const [chosen, setChosen] = useState<DocumentViewerTab | undefined>(initialTab)\n const tab = chosen && offered.includes(chosen) ? chosen : offered[0]\n\n const options: SegmentedOption<DocumentViewerTab>[] = offered.map((value) => ({\n value,\n label: labels[value],\n icon: TAB_ICONS[value],\n testId: TAB_TEST_IDS[value],\n }))\n\n // A question opens a new thread about the document, as the viewer's \"Chat\" does.\n const ask = (question: string) => {\n openNewConversation({ prompt: question })\n session.setNewChatDocumentId(baseId)\n }\n // The `/` menu: a skill's run is asked the same way, so its thread is about this document too.\n const [question, setQuestion] = useState('')\n const askInputRef = useRef<HTMLInputElement>(null)\n const slash = useSlashField({\n text: question,\n setText: setQuestion,\n inputRef: askInputRef,\n landing: 'chat',\n send: ask,\n })\n\n return (\n <Dialog open onOpenChange={(open) => !open && onClose()}>\n <DialogContent\n className=\"flex h-[90vh] max-w-[95vw] flex-col gap-0 p-0 sm:max-w-[95vw]\"\n data-testid=\"documents-dialog\"\n >\n <DialogHeader className=\"border-b px-4 py-3\">\n <DialogTitle className=\"flex min-w-0 items-center gap-2 pr-8 text-base\">\n <FileText className=\"size-4 shrink-0\" />\n <span className=\"truncate\" data-testid=\"documents-dialog-title\">\n {title}\n </span>\n </DialogTitle>\n <DialogDescription className=\"sr-only\">\n {offered.map((value) => labels[value]).join(', ')}: {title}\n </DialogDescription>\n {options.length > 1 && tab && (\n <SegmentedControl\n ariaLabel=\"Document view\"\n // A phone fits the three on one row: no label breaks over two lines.\n className=\"mt-2 w-fit max-w-full overflow-x-auto [&_button]:whitespace-nowrap max-sm:[&_button]:px-2.5\"\n value={tab}\n onChange={setChosen}\n options={options}\n />\n )}\n </DialogHeader>\n <div className=\"min-h-0 flex-1 overflow-hidden p-3\">\n {/* A view that fails to render says so here: the dialog and the page under it stay. */}\n <ErrorBoundary\n resetKey={`${documentId}|${tab}`}\n labels={{ title: \"This document couldn't be displayed\" }}\n testId=\"documents-dialog-error\"\n >\n {tab === 'review' && (\n <DocumentReview\n docId={baseId}\n doc={doc as ReviewDocument}\n workspaceId={workspaceId ?? undefined}\n activeChunkId={passageId}\n />\n )}\n {tab === 'document' && (\n <div className=\"h-full overflow-hidden\" data-testid=\"documents-dialog-viewer\">\n {renderDocument(documentId)}\n </div>\n )}\n {tab === 'ask' && (\n <div className=\"mx-auto max-w-2xl space-y-3 pt-6\" data-testid=\"doc-qa-panel\">\n <p className=\"text-sm text-muted-foreground\">{labels.askIntro}</p>\n {slash.launcher}\n <AskBar\n testId=\"doc-ask\"\n placeholder={labels.askPlaceholder.replace('{title}', title)}\n suggestions={[...askSuggestions]}\n onAsk={(text) => {\n if (!slash.startsSkill(text)) ask(text)\n }}\n value={question}\n onValueChange={setQuestion}\n onInputKeyDown={slash.onKeyDown}\n inputProps={slash.comboboxProps}\n inputRef={askInputRef}\n menu={slash.menu}\n />\n </div>\n )}\n </ErrorBoundary>\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n","/**\n * The files page's own viewer (a page without a host viewer): `DocumentViewerDialog`, with the\n * whole `ConnectedDocumentViewer` as its document view. The page lazy-loads this module, so the\n * viewer stays out of the page's chunk.\n */\nimport { ConnectedDocumentViewer } from '../../viewer/ConnectedDocumentViewer'\nimport {\n DocumentViewerDialog,\n type DocumentViewerDialogProps,\n} from '../../viewer/DocumentViewerDialog'\n\nexport interface FilesViewerDialogProps extends Omit<DocumentViewerDialogProps, 'renderDocument'> {\n /** Where html/react artifacts load their sandbox runtime from. */\n artifactRuntimeUrl?: string\n}\n\nexport function FilesViewerDialog({ artifactRuntimeUrl, ...props }: FilesViewerDialogProps) {\n return (\n <DocumentViewerDialog\n {...props}\n renderDocument={(id) => (\n <ConnectedDocumentViewer documentId={id} artifactRuntimeUrl={artifactRuntimeUrl} />\n )}\n />\n )\n}\n"]}
|