@arbidocs/blocks 0.5.125 → 0.5.127
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/README.md +19 -0
- package/dist/{ClippingMediaViewer-ZFEX5A3U.cjs → ClippingMediaViewer-47BAXNLO.cjs} +10 -11
- package/dist/ClippingMediaViewer-47BAXNLO.cjs.map +1 -0
- package/dist/{ClippingPdfViewer-3LRTEPHV.cjs → ClippingPdfViewer-D5BYHEAH.cjs} +16 -14
- package/dist/ClippingPdfViewer-D5BYHEAH.cjs.map +1 -0
- package/dist/ConnectedCallDock-XJOYVVAH.cjs +6 -6
- package/dist/ConnectedCallRoom-CUDYAPQK.cjs +6 -6
- package/dist/{ConnectedNativeDocxComparison-7QQ55JIO.cjs → ConnectedNativeDocxComparison-JUF2TI2P.cjs} +12 -12
- package/dist/{ConnectedNativeDocxComparison-7QQ55JIO.cjs.map → ConnectedNativeDocxComparison-JUF2TI2P.cjs.map} +1 -1
- package/dist/{ConnectedPresentation-L32JPRFI.cjs → ConnectedPresentation-SI3L77J4.cjs} +35 -36
- package/dist/ConnectedPresentation-SI3L77J4.cjs.map +1 -0
- package/dist/{ConnectedProductionSetDialog-4EAY6KAZ.cjs → ConnectedProductionSetDialog-LHB4VQWC.cjs} +3 -3
- package/dist/{ConnectedProductionSetDialog-4EAY6KAZ.cjs.map → ConnectedProductionSetDialog-LHB4VQWC.cjs.map} +1 -1
- package/dist/{ConnectedSlidesTab-P7GGNUTO.cjs → ConnectedSlidesTab-E76OVY34.cjs} +38 -44
- package/dist/ConnectedSlidesTab-E76OVY34.cjs.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-7NJ3N52V.cjs → ConnectedStreamedWordArtifact-Q64DRRQD.cjs} +12 -12
- package/dist/{ConnectedStreamedWordArtifact-7NJ3N52V.cjs.map → ConnectedStreamedWordArtifact-Q64DRRQD.cjs.map} +1 -1
- package/dist/{DocumentReviewCard-BFPOFQXI.cjs → DocumentReviewCard-M53XFLI2.cjs} +16 -16
- package/dist/{DocumentReviewCard-BFPOFQXI.cjs.map → DocumentReviewCard-M53XFLI2.cjs.map} +1 -1
- package/dist/{FilesViewerDialog-MHUVEZ7M.cjs → FilesViewerDialog-V6FSRQTP.cjs} +33 -34
- package/dist/FilesViewerDialog-V6FSRQTP.cjs.map +1 -0
- package/dist/{NativeDocxEditor-SIRYPMBN.cjs → NativeDocxEditor-2PTEK6ND.cjs} +6 -6
- package/dist/{NativeDocxEditor-SIRYPMBN.cjs.map → NativeDocxEditor-2PTEK6ND.cjs.map} +1 -1
- package/dist/{SpotlightStrip-ED22UYTM.cjs → SpotlightStrip-QQ2WUI32.cjs} +28 -29
- package/dist/SpotlightStrip-QQ2WUI32.cjs.map +1 -0
- package/dist/{WorkspaceTableView-MIFYXV3G.cjs → WorkspaceTableView-3XYAV4BV.cjs} +8 -8
- package/dist/{WorkspaceTableView-MIFYXV3G.cjs.map → WorkspaceTableView-3XYAV4BV.cjs.map} +1 -1
- package/dist/agents/index.cjs +215 -215
- package/dist/ai-IEIR7SC2.cjs +3 -3
- package/dist/auth/index.cjs +1 -1
- package/dist/calls/index.cjs +2 -2
- package/dist/chat/index.cjs +6 -6
- package/dist/{chunk-GAMRVB3I.cjs → chunk-23I5EUZA.cjs} +65 -10
- package/dist/chunk-23I5EUZA.cjs.map +1 -0
- package/dist/{chunk-ZZZITHGK.cjs → chunk-26SFI2BH.cjs} +16 -3
- package/dist/chunk-26SFI2BH.cjs.map +1 -0
- package/dist/{chunk-OGK377NL.cjs → chunk-2SU37RZA.cjs} +409 -42
- package/dist/chunk-2SU37RZA.cjs.map +1 -0
- package/dist/{chunk-CQ2RJYE2.cjs → chunk-3IH55CDE.cjs} +3 -3
- package/dist/{chunk-CQ2RJYE2.cjs.map → chunk-3IH55CDE.cjs.map} +1 -1
- package/dist/{chunk-AS6QZETU.cjs → chunk-5QERK4PK.cjs} +35 -35
- package/dist/{chunk-AS6QZETU.cjs.map → chunk-5QERK4PK.cjs.map} +1 -1
- package/dist/{chunk-AISYXX4M.cjs → chunk-7NLO7ASW.cjs} +4 -4
- package/dist/{chunk-AISYXX4M.cjs.map → chunk-7NLO7ASW.cjs.map} +1 -1
- package/dist/{chunk-QIK7E6VF.cjs → chunk-7PN3YENO.cjs} +4 -4
- package/dist/{chunk-QIK7E6VF.cjs.map → chunk-7PN3YENO.cjs.map} +1 -1
- package/dist/{chunk-JY7UUZQG.cjs → chunk-7Q46YAX4.cjs} +74 -71
- package/dist/chunk-7Q46YAX4.cjs.map +1 -0
- package/dist/{chunk-J3FFSEKO.cjs → chunk-ADDQKZ5I.cjs} +4 -4
- package/dist/{chunk-J3FFSEKO.cjs.map → chunk-ADDQKZ5I.cjs.map} +1 -1
- package/dist/{chunk-L6HTZIBD.cjs → chunk-ALK3PUUB.cjs} +3 -3
- package/dist/{chunk-L6HTZIBD.cjs.map → chunk-ALK3PUUB.cjs.map} +1 -1
- package/dist/{chunk-3ZZZO4F7.cjs → chunk-BY3QA3S5.cjs} +9 -9
- package/dist/{chunk-3ZZZO4F7.cjs.map → chunk-BY3QA3S5.cjs.map} +1 -1
- package/dist/{chunk-3UP32FM3.cjs → chunk-CQQQIZU4.cjs} +5 -5
- package/dist/{chunk-3UP32FM3.cjs.map → chunk-CQQQIZU4.cjs.map} +1 -1
- package/dist/{chunk-YOEP3I4V.cjs → chunk-E3L5DB5F.cjs} +5 -5
- package/dist/{chunk-YOEP3I4V.cjs.map → chunk-E3L5DB5F.cjs.map} +1 -1
- package/dist/{chunk-UA7HOLAZ.cjs → chunk-ESVRVZ53.cjs} +5 -5
- package/dist/{chunk-UA7HOLAZ.cjs.map → chunk-ESVRVZ53.cjs.map} +1 -1
- package/dist/{chunk-2K6IMIVL.cjs → chunk-GNZAH6UI.cjs} +3 -3
- package/dist/{chunk-2K6IMIVL.cjs.map → chunk-GNZAH6UI.cjs.map} +1 -1
- package/dist/{chunk-KA3F6TIH.cjs → chunk-IWHP7FAB.cjs} +12 -5
- package/dist/chunk-IWHP7FAB.cjs.map +1 -0
- package/dist/{chunk-ORNLCBNE.cjs → chunk-JVEDKKNO.cjs} +43 -4
- package/dist/chunk-JVEDKKNO.cjs.map +1 -0
- package/dist/{chunk-6JMW3IJ2.cjs → chunk-JVLOIIA7.cjs} +103 -100
- package/dist/chunk-JVLOIIA7.cjs.map +1 -0
- package/dist/{chunk-UUENH4BJ.cjs → chunk-KXIRVKCJ.cjs} +3 -3
- package/dist/{chunk-UUENH4BJ.cjs.map → chunk-KXIRVKCJ.cjs.map} +1 -1
- package/dist/{chunk-YVO6Z5BS.cjs → chunk-M6WVIGYP.cjs} +10 -10
- package/dist/{chunk-YVO6Z5BS.cjs.map → chunk-M6WVIGYP.cjs.map} +1 -1
- package/dist/{chunk-PSB64T43.cjs → chunk-MLA2BJ2Y.cjs} +28 -28
- package/dist/{chunk-PSB64T43.cjs.map → chunk-MLA2BJ2Y.cjs.map} +1 -1
- package/dist/{chunk-B3R62764.cjs → chunk-MMSHIIKG.cjs} +6 -6
- package/dist/{chunk-B3R62764.cjs.map → chunk-MMSHIIKG.cjs.map} +1 -1
- package/dist/{chunk-ENOPKX7E.cjs → chunk-MXBXZXXQ.cjs} +3 -3
- package/dist/{chunk-ENOPKX7E.cjs.map → chunk-MXBXZXXQ.cjs.map} +1 -1
- package/dist/chunk-NTDQQLDD.cjs +18 -0
- package/dist/{chunk-IRGRMJPP.cjs.map → chunk-NTDQQLDD.cjs.map} +1 -1
- package/dist/{chunk-PVJ5ODDB.cjs → chunk-Q6IKXWPG.cjs} +4 -4
- package/dist/{chunk-PVJ5ODDB.cjs.map → chunk-Q6IKXWPG.cjs.map} +1 -1
- package/dist/{chunk-4LP5MJGQ.cjs → chunk-QG2U2JGX.cjs} +4 -4
- package/dist/{chunk-4LP5MJGQ.cjs.map → chunk-QG2U2JGX.cjs.map} +1 -1
- package/dist/{chunk-MVXHTAJ4.cjs → chunk-QWVUBTW3.cjs} +9 -9
- package/dist/{chunk-MVXHTAJ4.cjs.map → chunk-QWVUBTW3.cjs.map} +1 -1
- package/dist/{chunk-OHWHYVKG.cjs → chunk-T73BHNQX.cjs} +3 -3
- package/dist/{chunk-OHWHYVKG.cjs.map → chunk-T73BHNQX.cjs.map} +1 -1
- package/dist/{chunk-PWBRE7JA.cjs → chunk-VLQCLQAS.cjs} +23 -10
- package/dist/chunk-VLQCLQAS.cjs.map +1 -0
- package/dist/{chunk-ADPRIBSH.cjs → chunk-X7ALF4MP.cjs} +7 -7
- package/dist/{chunk-ADPRIBSH.cjs.map → chunk-X7ALF4MP.cjs.map} +1 -1
- package/dist/{chunk-7RJZIPLE.cjs → chunk-YP5EBGLU.cjs} +33 -33
- package/dist/{chunk-7RJZIPLE.cjs.map → chunk-YP5EBGLU.cjs.map} +1 -1
- package/dist/{chunk-TSFNLY3K.cjs → chunk-ZCU72Q76.cjs} +192 -166
- package/dist/chunk-ZCU72Q76.cjs.map +1 -0
- package/dist/{chunk-BLIO3B7Z.cjs → chunk-ZYGAXD3N.cjs} +3 -3
- package/dist/{chunk-BLIO3B7Z.cjs.map → chunk-ZYGAXD3N.cjs.map} +1 -1
- package/dist/connect/docx.cjs +16 -16
- package/dist/connect/index.cjs +1095 -1114
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/viewer.cjs +26 -27
- package/dist/connection/ai.d.ts +1 -0
- package/dist/connection/docx/ConnectedNativeDocxEditor.js +4 -5
- package/dist/connection/docx/ConnectedNativeDocxEditor.js.map +2 -2
- package/dist/connection/docx/save-native-version.d.ts +3 -0
- package/dist/connection/docx/save-native-version.js +19 -0
- package/dist/connection/docx/save-native-version.js.map +7 -0
- package/dist/connection/presentation/ClippingPdfViewer.js +8 -5
- package/dist/connection/presentation/ClippingPdfViewer.js.map +2 -2
- package/dist/connection/presentation/ConnectedSlidesTab.js +8 -13
- package/dist/connection/presentation/ConnectedSlidesTab.js.map +2 -2
- package/dist/connection/presentation/usePresentationController.js +24 -15
- package/dist/connection/presentation/usePresentationController.js.map +2 -2
- package/dist/connection/presentation/usePresentationFiles.d.ts +2 -1
- package/dist/connection/presentation/usePresentationFiles.js +15 -6
- package/dist/connection/presentation/usePresentationFiles.js.map +2 -2
- package/dist/connection/remote-control/ConnectedRemoteControlConsent.js +6 -3
- package/dist/connection/remote-control/ConnectedRemoteControlConsent.js.map +2 -2
- package/dist/connection/remote-control/ConnectedRemoteControlIndicator.js +12 -2
- package/dist/connection/remote-control/ConnectedRemoteControlIndicator.js.map +2 -2
- package/dist/connection/remote-control/ConnectedRemoteControlSwitch.js +1 -1
- package/dist/connection/remote-control/ConnectedRemoteControlSwitch.js.map +1 -1
- package/dist/connection/remote-control/browser-diagnostics.d.ts +7 -0
- package/dist/connection/remote-control/browser-diagnostics.js +109 -0
- package/dist/connection/remote-control/browser-diagnostics.js.map +7 -0
- package/dist/connection/remote-control/remoteControl.d.ts +9 -1
- package/dist/connection/remote-control/remoteControl.js +130 -10
- package/dist/connection/remote-control/remoteControl.js.map +2 -2
- package/dist/connection/remote-control/screen-sharing.d.ts +11 -0
- package/dist/connection/remote-control/screen-sharing.js +78 -0
- package/dist/connection/remote-control/screen-sharing.js.map +7 -0
- package/dist/connection/report-problem/screen-capture.d.ts +1 -0
- package/dist/connection/report-problem/screen-capture.js +2 -1
- package/dist/connection/report-problem/screen-capture.js.map +2 -2
- package/dist/connection/search/ConnectedSearchPage.d.ts +0 -11
- package/dist/connection/search/ConnectedSearchPage.js +3 -0
- package/dist/connection/search/ConnectedSearchPage.js.map +2 -2
- package/dist/connection/search/SearchResultRows.js +75 -43
- package/dist/connection/search/SearchResultRows.js.map +2 -2
- package/dist/connection/viewer/CleanViewControl.d.ts +3 -1
- package/dist/connection/viewer/CleanViewControl.js +5 -1
- package/dist/connection/viewer/CleanViewControl.js.map +2 -2
- package/dist/connection/viewer/ConnectedDocumentViewer.js +1 -1
- package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
- package/dist/connection/viewer/useCleanView.d.ts +1 -1
- package/dist/connection/viewer/useCleanView.js +2 -2
- package/dist/connection/viewer/useCleanView.js.map +2 -2
- package/dist/connection/viewer/useViewedDocument.d.ts +1 -0
- package/dist/document-tools/index.cjs +20 -20
- package/dist/docx/NativeDocxEditor.d.ts +2 -1
- package/dist/docx/NativeDocxEditor.js +34 -7
- package/dist/docx/NativeDocxEditor.js.map +2 -2
- package/dist/docx/index.cjs +38 -38
- package/dist/docx/useVersionAutosave.d.ts +10 -0
- package/dist/docx/useVersionAutosave.js +36 -0
- package/dist/docx/useVersionAutosave.js.map +7 -0
- package/dist/embed/index.cjs +19 -19
- package/dist/facts/index.cjs +64 -64
- package/dist/files/index.cjs +223 -223
- package/dist/index.cjs +542 -542
- package/dist/presentation/ClipCaptureOverlay.js +14 -1
- package/dist/presentation/ClipCaptureOverlay.js.map +2 -2
- package/dist/presentation/ClipImage.js +7 -4
- package/dist/presentation/ClipImage.js.map +2 -2
- package/dist/presentation/ClipTray.js +11 -7
- package/dist/presentation/ClipTray.js.map +2 -2
- package/dist/presentation/SlidesEditor.js +6 -2
- package/dist/presentation/SlidesEditor.js.map +2 -2
- package/dist/presentation/store.d.ts +2 -0
- package/dist/presentation/store.js +15 -0
- package/dist/presentation/store.js.map +3 -3
- package/dist/settings/index.cjs +146 -146
- package/dist/shell/RemoteControlPill.d.ts +2 -1
- package/dist/shell/RemoteControlPill.js +10 -3
- package/dist/shell/RemoteControlPill.js.map +2 -2
- package/dist/shell/index.cjs +21 -21
- package/dist/site/index.cjs +6 -6
- package/dist/studio/index.cjs +9 -9
- package/dist/workflow-canvas/index.cjs +34 -34
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/ClippingMediaViewer-ZFEX5A3U.cjs.map +0 -1
- package/dist/ClippingPdfViewer-3LRTEPHV.cjs.map +0 -1
- package/dist/ConnectedPresentation-L32JPRFI.cjs.map +0 -1
- package/dist/ConnectedSlidesTab-P7GGNUTO.cjs.map +0 -1
- package/dist/FilesViewerDialog-MHUVEZ7M.cjs.map +0 -1
- package/dist/SpotlightStrip-ED22UYTM.cjs.map +0 -1
- package/dist/chunk-6JMW3IJ2.cjs.map +0 -1
- package/dist/chunk-GAMRVB3I.cjs.map +0 -1
- package/dist/chunk-GFUOCGY6.cjs +0 -32
- package/dist/chunk-GFUOCGY6.cjs.map +0 -1
- package/dist/chunk-IRGRMJPP.cjs +0 -18
- package/dist/chunk-JY7UUZQG.cjs.map +0 -1
- package/dist/chunk-KA3F6TIH.cjs.map +0 -1
- package/dist/chunk-OGK377NL.cjs.map +0 -1
- package/dist/chunk-ORNLCBNE.cjs.map +0 -1
- package/dist/chunk-PWBRE7JA.cjs.map +0 -1
- package/dist/chunk-TSFNLY3K.cjs.map +0 -1
- package/dist/chunk-ZZZITHGK.cjs.map +0 -1
|
@@ -32,34 +32,50 @@ const FlatResultRow = memo(function FlatResultRow2({
|
|
|
32
32
|
labels
|
|
33
33
|
}) {
|
|
34
34
|
const handleClick = useCallback((e) => onOpen(e, hit), [onOpen, hit]);
|
|
35
|
-
return /* @__PURE__ */
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
/* @__PURE__ */
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
35
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
SearchHit,
|
|
38
|
+
{
|
|
39
|
+
active: useIsOpenPassage(hit.chunkExtId),
|
|
40
|
+
header: (
|
|
41
|
+
// No `onClick` on the pill: it would render a real <button> inside the card's
|
|
42
|
+
// role="button" target (invalid nesting). The card already opens the passage.
|
|
43
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
|
|
44
|
+
/* @__PURE__ */ jsx(
|
|
45
|
+
PassagePill,
|
|
46
|
+
{
|
|
47
|
+
icon: /* @__PURE__ */ jsx(HtmlIcon, { size: 16, className: "flex-shrink-0" }),
|
|
48
|
+
documentTitle: hit.docTitle,
|
|
49
|
+
pageNumber: hit.page,
|
|
50
|
+
passageIndex: hit.index,
|
|
51
|
+
labelMaxWidth: "max-w-none"
|
|
52
|
+
}
|
|
53
|
+
),
|
|
54
|
+
/* @__PURE__ */ jsx(MeaningMatchBadge, { content: hit.content, terms, labels })
|
|
55
|
+
] })
|
|
56
|
+
),
|
|
57
|
+
content: hit.content,
|
|
58
|
+
terms,
|
|
59
|
+
renderSnippet,
|
|
60
|
+
onClick: handleClick,
|
|
61
|
+
testId: `search-result-flat-${position}`
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
/* @__PURE__ */ jsx(
|
|
65
|
+
"button",
|
|
66
|
+
{
|
|
67
|
+
type: "button",
|
|
68
|
+
className: "rounded border px-2 py-0.5 text-xs",
|
|
69
|
+
onClick: (event) => {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
event.stopPropagation();
|
|
72
|
+
event.currentTarget.dataset.clip = "true";
|
|
73
|
+
onOpen(event, hit);
|
|
74
|
+
},
|
|
75
|
+
children: "Clip"
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
] });
|
|
63
79
|
});
|
|
64
80
|
const GroupedResultRow = memo(function GroupedResultRow2({
|
|
65
81
|
hit,
|
|
@@ -69,21 +85,37 @@ const GroupedResultRow = memo(function GroupedResultRow2({
|
|
|
69
85
|
labels
|
|
70
86
|
}) {
|
|
71
87
|
const handleClick = useCallback((e) => onOpen(e, hit), [onOpen, hit]);
|
|
72
|
-
return /* @__PURE__ */
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
/* @__PURE__ */
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
89
|
+
/* @__PURE__ */ jsx(
|
|
90
|
+
SearchHit,
|
|
91
|
+
{
|
|
92
|
+
active: useIsOpenPassage(hit.chunkExtId ?? hit.id),
|
|
93
|
+
header: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
|
|
94
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: hit.page ? labels.page(hit.page) : labels.passage }),
|
|
95
|
+
/* @__PURE__ */ jsx(MeaningMatchBadge, { content: hit.content, terms, labels })
|
|
96
|
+
] }),
|
|
97
|
+
content: hit.content,
|
|
98
|
+
terms,
|
|
99
|
+
renderSnippet,
|
|
100
|
+
onClick: handleClick,
|
|
101
|
+
testId
|
|
102
|
+
}
|
|
103
|
+
),
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
"button",
|
|
106
|
+
{
|
|
107
|
+
type: "button",
|
|
108
|
+
className: "rounded border px-2 py-0.5 text-xs",
|
|
109
|
+
onClick: (event) => {
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
event.stopPropagation();
|
|
112
|
+
event.currentTarget.dataset.clip = "true";
|
|
113
|
+
onOpen(event, hit);
|
|
114
|
+
},
|
|
115
|
+
children: "Clip"
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
] });
|
|
87
119
|
});
|
|
88
120
|
const SearchGroupRowHeader = memo(function SearchGroupRowHeader2({
|
|
89
121
|
group,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/connection/search/SearchResultRows.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * The search page's rows: a passage in the flat list, a passage inside its document's group, and\n * the group's header. Each is memoized against stable props from the page, so paging or moving\n * the threshold doesn't re-render rows.\n */\n\nimport { memo, useCallback, type MouseEvent, type ReactNode } from 'react'\nimport { HtmlIcon, useArbiSessionState, type SearchChunk } from '@arbidocs/react'\nimport { Badge } from '@arbidocs/react/ui'\nimport { PassagePill } from '../../citations/PassagePill'\nimport { SearchGroupHeader } from '../../retrieval/SearchGroupHeader'\nimport { SearchHit } from '../../retrieval/SearchHit'\nimport { renderSearchSnippet as renderSnippet } from '../../retrieval/SearchSnippet'\nimport { isMeaningMatch, type SearchDocumentGroup } from '../../retrieval/search-results'\n\nexport interface SearchRowLabels {\n /** Badge on a passage that contains none of the query's words. */\n meaningMatch: string\n meaningMatchTitle: string\n /** The page a grouped passage is on. */\n page: (page: number) => string\n /** A grouped passage without a page. */\n passage: string\n}\n\nexport const DEFAULT_SEARCH_ROW_LABELS: SearchRowLabels = {\n meaningMatch: 'Matched by meaning',\n meaningMatchTitle: 'None of your search words appear in this passage. It matched by meaning.',\n page: (page) => `p.${page}`,\n passage: 'Passage',\n}\n\n/** Whether the passage is the one open in the document viewer. */\nfunction useIsOpenPassage(chunkExtId: string | undefined): boolean {\n return useArbiSessionState((s) => !!chunkExtId && s.viewingDocument?.passageId === chunkExtId)\n}\n\nfunction MeaningMatchBadge({\n content,\n terms,\n labels,\n}: {\n content: string\n terms: string[]\n labels: SearchRowLabels\n}) {\n return isMeaningMatch(content, terms) ? (\n <Badge variant=\"outline\" className=\"text-muted-foreground\" title={labels.meaningMatchTitle}>\n {labels.meaningMatch}\n </Badge>\n ) : null\n}\n\ninterface RowProps {\n hit: SearchChunk\n terms: string[]\n onOpen: (e: MouseEvent, hit: SearchChunk) => void\n labels: SearchRowLabels\n}\n\nexport const FlatResultRow = memo(function FlatResultRow({\n hit,\n position,\n terms,\n onOpen,\n labels,\n}: RowProps & { position: number }) {\n const handleClick = useCallback((e: MouseEvent) => onOpen(e, hit), [onOpen, hit])\n return (\n <SearchHit\n
|
|
5
|
-
"mappings": ";AA+CI,
|
|
4
|
+
"sourcesContent": ["/**\n * The search page's rows: a passage in the flat list, a passage inside its document's group, and\n * the group's header. Each is memoized against stable props from the page, so paging or moving\n * the threshold doesn't re-render rows.\n */\n\nimport { memo, useCallback, type MouseEvent, type ReactNode } from 'react'\nimport { HtmlIcon, useArbiSessionState, type SearchChunk } from '@arbidocs/react'\nimport { Badge } from '@arbidocs/react/ui'\nimport { PassagePill } from '../../citations/PassagePill'\nimport { SearchGroupHeader } from '../../retrieval/SearchGroupHeader'\nimport { SearchHit } from '../../retrieval/SearchHit'\nimport { renderSearchSnippet as renderSnippet } from '../../retrieval/SearchSnippet'\nimport { isMeaningMatch, type SearchDocumentGroup } from '../../retrieval/search-results'\n\nexport interface SearchRowLabels {\n /** Badge on a passage that contains none of the query's words. */\n meaningMatch: string\n meaningMatchTitle: string\n /** The page a grouped passage is on. */\n page: (page: number) => string\n /** A grouped passage without a page. */\n passage: string\n}\n\nexport const DEFAULT_SEARCH_ROW_LABELS: SearchRowLabels = {\n meaningMatch: 'Matched by meaning',\n meaningMatchTitle: 'None of your search words appear in this passage. It matched by meaning.',\n page: (page) => `p.${page}`,\n passage: 'Passage',\n}\n\n/** Whether the passage is the one open in the document viewer. */\nfunction useIsOpenPassage(chunkExtId: string | undefined): boolean {\n return useArbiSessionState((s) => !!chunkExtId && s.viewingDocument?.passageId === chunkExtId)\n}\n\nfunction MeaningMatchBadge({\n content,\n terms,\n labels,\n}: {\n content: string\n terms: string[]\n labels: SearchRowLabels\n}) {\n return isMeaningMatch(content, terms) ? (\n <Badge variant=\"outline\" className=\"text-muted-foreground\" title={labels.meaningMatchTitle}>\n {labels.meaningMatch}\n </Badge>\n ) : null\n}\n\ninterface RowProps {\n hit: SearchChunk\n terms: string[]\n onOpen: (e: MouseEvent, hit: SearchChunk) => void\n labels: SearchRowLabels\n}\n\nexport const FlatResultRow = memo(function FlatResultRow({\n hit,\n position,\n terms,\n onOpen,\n labels,\n}: RowProps & { position: number }) {\n const handleClick = useCallback((e: MouseEvent) => onOpen(e, hit), [onOpen, hit])\n return (\n <div>\n <SearchHit\n active={useIsOpenPassage(hit.chunkExtId)}\n header={\n // No `onClick` on the pill: it would render a real <button> inside the card's\n // role=\"button\" target (invalid nesting). The card already opens the passage.\n <div className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <PassagePill\n icon={<HtmlIcon size={16} className=\"flex-shrink-0\" />}\n documentTitle={hit.docTitle}\n pageNumber={hit.page}\n passageIndex={hit.index}\n labelMaxWidth=\"max-w-none\"\n />\n <MeaningMatchBadge content={hit.content} terms={terms} labels={labels} />\n </div>\n }\n content={hit.content}\n terms={terms}\n renderSnippet={renderSnippet}\n onClick={handleClick}\n testId={`search-result-flat-${position}`}\n />\n <button\n type=\"button\"\n className=\"rounded border px-2 py-0.5 text-xs\"\n onClick={(event) => {\n event.preventDefault()\n event.stopPropagation()\n event.currentTarget.dataset.clip = 'true'\n onOpen(event, hit)\n }}\n >\n Clip\n </button>\n </div>\n )\n})\n\nexport const GroupedResultRow = memo(function GroupedResultRow({\n hit,\n testId,\n terms,\n onOpen,\n labels,\n}: RowProps & { testId: string }) {\n const handleClick = useCallback((e: MouseEvent) => onOpen(e, hit), [onOpen, hit])\n return (\n <div>\n <SearchHit\n active={useIsOpenPassage(hit.chunkExtId ?? hit.id)}\n header={\n <div className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n {hit.page ? labels.page(hit.page) : labels.passage}\n </span>\n <MeaningMatchBadge content={hit.content} terms={terms} labels={labels} />\n </div>\n }\n content={hit.content}\n terms={terms}\n renderSnippet={renderSnippet}\n onClick={handleClick}\n testId={testId}\n />\n <button\n type=\"button\"\n className=\"rounded border px-2 py-0.5 text-xs\"\n onClick={(event) => {\n event.preventDefault()\n event.stopPropagation()\n event.currentTarget.dataset.clip = 'true'\n onOpen(event, hit)\n }}\n >\n Clip\n </button>\n </div>\n )\n})\n\nexport const SearchGroupRowHeader = memo(function SearchGroupRowHeader({\n group,\n source,\n isExpanded,\n onToggle,\n}: {\n group: SearchDocumentGroup\n /** The document's chip. */\n source: ReactNode\n isExpanded: boolean\n onToggle: (docId: string) => void\n}) {\n return (\n <SearchGroupHeader\n groupId={group.docId}\n hitCount={group.results.length}\n isExpanded={isExpanded}\n onToggle={onToggle}\n source={source}\n />\n )\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["FlatResultRow", "GroupedResultRow", "SearchGroupRowHeader"]
|
|
7
7
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
1
2
|
/**
|
|
2
3
|
* Over the viewer's clean view: Full screen, and Show controls (leave the clean view). It shows
|
|
3
4
|
* while the pointer moves or a key is pressed and fades after a moment, so a share rarely
|
|
4
5
|
* catches it.
|
|
5
6
|
*/
|
|
6
|
-
export declare function CleanViewControl({ onExit }: {
|
|
7
|
+
export declare function CleanViewControl({ onExit, children, }: {
|
|
7
8
|
onExit: () => void;
|
|
9
|
+
children?: ReactNode;
|
|
8
10
|
}): import("react").JSX.Element;
|
|
@@ -5,7 +5,10 @@ import { Maximize, PanelTop } from "lucide-react";
|
|
|
5
5
|
import { Button, cn } from "@arbidocs/react/ui";
|
|
6
6
|
import { toggleFullscreen } from "../../presentation/usePresenterKeys.js";
|
|
7
7
|
const IDLE_MS = 2e3;
|
|
8
|
-
function CleanViewControl({
|
|
8
|
+
function CleanViewControl({
|
|
9
|
+
onExit,
|
|
10
|
+
children
|
|
11
|
+
}) {
|
|
9
12
|
const [view, setView] = useState(null);
|
|
10
13
|
const [shown, setShown] = useState(true);
|
|
11
14
|
const ref = useCallback((node) => {
|
|
@@ -37,6 +40,7 @@ function CleanViewControl({ onExit }) {
|
|
|
37
40
|
),
|
|
38
41
|
"data-testid": "viewer-clean-control",
|
|
39
42
|
children: [
|
|
43
|
+
children,
|
|
40
44
|
/* @__PURE__ */ jsxs(
|
|
41
45
|
Button,
|
|
42
46
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/connection/viewer/CleanViewControl.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useCallback, useEffect, useState } from 'react'\nimport { Maximize, PanelTop } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { toggleFullscreen } from '../../presentation/usePresenterKeys'\n\nconst IDLE_MS = 2000\n\n/**\n * Over the viewer's clean view: Full screen, and Show controls (leave the clean view). It shows\n * while the pointer moves or a key is pressed and fades after a moment, so a share rarely\n * catches it.\n */\nexport function CleanViewControl({
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["import { useCallback, useEffect, useState, type ReactNode } from 'react'\nimport { Maximize, PanelTop } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { toggleFullscreen } from '../../presentation/usePresenterKeys'\n\nconst IDLE_MS = 2000\n\n/**\n * Over the viewer's clean view: Full screen, and Show controls (leave the clean view). It shows\n * while the pointer moves or a key is pressed and fades after a moment, so a share rarely\n * catches it.\n */\nexport function CleanViewControl({\n onExit,\n children,\n}: {\n onExit: () => void\n children?: ReactNode\n}) {\n const [view, setView] = useState<Window | null>(null)\n const [shown, setShown] = useState(true)\n const ref = useCallback((node: HTMLDivElement | null) => {\n setView(node?.ownerDocument.defaultView ?? null)\n }, [])\n\n useEffect(() => {\n if (!view) return\n let timer = view.setTimeout(() => setShown(false), IDLE_MS)\n const wake = () => {\n setShown(true)\n view.clearTimeout(timer)\n timer = view.setTimeout(() => setShown(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\n return (\n <div\n ref={ref}\n className={cn(\n 'absolute right-3 top-3 z-20 flex gap-1 rounded-md bg-background/90 p-1 shadow-md transition-opacity',\n shown ? 'opacity-100' : 'pointer-events-none opacity-0'\n )}\n data-testid=\"viewer-clean-control\"\n >\n {children}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-7\"\n onClick={() => view && toggleFullscreen(view)}\n >\n <Maximize className=\"size-3.5\" />\n Full screen\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-7\"\n onClick={onExit}\n data-testid=\"viewer-clean-exit\"\n >\n <PanelTop className=\"size-3.5\" />\n Show controls\n </Button>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AAoDM,SAOE,KAPF;AApDN,SAAS,aAAa,WAAW,gBAAgC;AACjE,SAAS,UAAU,gBAAgB;AACnC,SAAS,QAAQ,UAAU;AAC3B,SAAS,wBAAwB;AAEjC,MAAM,UAAU;AAOT,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAwB,IAAI;AACpD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,IAAI;AACvC,QAAM,MAAM,YAAY,CAAC,SAAgC;AACvD,YAAQ,MAAM,cAAc,eAAe,IAAI;AAAA,EACjD,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,QAAI,QAAQ,KAAK,WAAW,MAAM,SAAS,KAAK,GAAG,OAAO;AAC1D,UAAM,OAAO,MAAM;AACjB,eAAS,IAAI;AACb,WAAK,aAAa,KAAK;AACvB,cAAQ,KAAK,WAAW,MAAM,SAAS,KAAK,GAAG,OAAO;AAAA,IACxD;AACA,SAAK,iBAAiB,eAAe,IAAI;AACzC,SAAK,iBAAiB,WAAW,IAAI;AACrC,WAAO,MAAM;AACX,WAAK,aAAa,KAAK;AACvB,WAAK,oBAAoB,eAAe,IAAI;AAC5C,WAAK,oBAAoB,WAAW,IAAI;AAAA,IAC1C;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,QAAQ,gBAAgB;AAAA,MAC1B;AAAA,MACA,eAAY;AAAA,MAEX;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS,MAAM,QAAQ,iBAAiB,IAAI;AAAA,YAE5C;AAAA,kCAAC,YAAS,WAAU,YAAW;AAAA,cAAE;AAAA;AAAA;AAAA,QAEnC;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,WAAU;AAAA,YACV,SAAS;AAAA,YACT,eAAY;AAAA,YAEZ;AAAA,kCAAC,YAAS,WAAU,YAAW;AAAA,cAAE;AAAA;AAAA;AAAA,QAEnC;AAAA;AAAA;AAAA,EACF;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -425,7 +425,7 @@ function DocumentViewerContent({
|
|
|
425
425
|
isComparing
|
|
426
426
|
});
|
|
427
427
|
const clip = useViewerClipping(annotatable || !!pdfBlob && (isImage || isVideo), isCompact);
|
|
428
|
-
const clean = useCleanView(clip.layer);
|
|
428
|
+
const clean = useCleanView(clip.layer, clip.button);
|
|
429
429
|
const signatureBanner = !isDraft && !liveKind && !snapshotDocumentId && /* @__PURE__ */ jsx(
|
|
430
430
|
SignatureRequestBanner,
|
|
431
431
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/connection/viewer/ConnectedDocumentViewer.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * The whole document viewer on the signed-in session: a document (or one of its versions, read\n * only) as its PDF, its text, the Word editor, a sheet, an image, a recording or a live artifact;\n * its versions and comparisons; markup, signing and signature requests; sharing, Email, Translate\n * and Finalise. Runs under any host (`useConnectedWorkspace`): the open document, tab and comparison\n * are the session state's, navigation the `BlocksEnvironment`'s, and what only the host knows comes\n * as its host config's `viewer`.\n */\n\nimport { lazy, Suspense, useCallback, useEffect, useRef, useState, type ReactNode } from 'react'\nimport {\n ChevronDown,\n Languages,\n Link2,\n Mail,\n MessageSquare,\n MessageSquarePlus,\n PenLine,\n Signature,\n Users,\n} from 'lucide-react'\nimport { useArbi, useArbiSessionState, useArbiSessionStore } from '@arbidocs/react'\nimport { findVersion, parseVersionRef, versionLabel } from '@arbidocs/react/artifacts'\nimport {\n SIGNED_LOCKED_REASON,\n canAnnotate,\n useDocumentMarkup,\n useDocumentSignatures,\n useDocumentTools,\n type SignatureAppearance,\n} from '@arbidocs/react/document-tools'\nimport { XlsxViewer, cycleZoom } from '@arbidocs/react/viewers'\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n getEntityLabel,\n SharingEntity,\n} from '@arbidocs/react/ui'\nimport {\n ArtifactCodeView,\n ArtifactCompareBar,\n ArtifactPreview,\n VersionTimeline,\n} from '../../artifacts'\nimport { latestThreadOfDocument, useRegisterOpenDocument } from '@arbidocs/react/shell'\nimport { ShareControl } from '../../collaboration/sharing/ShareControl'\nimport {\n ViewerCaptureDraft,\n ViewerDraftKind,\n ViewerDraftTitle,\n ViewerRelatedDocuments,\n} from './drafts'\nimport {\n AnnotateButton,\n DownloadMarkupButton,\n FileShareDialog,\n MarkupNotices,\n MarkupViewNote,\n PlaceMySignatureMenuItems,\n ShowOriginalButton,\n SignDocumentDialog,\n SignedEditNote,\n SignatureRequestBanner,\n SignatureStatus,\n VersionSnapshotBar,\n} from '../../document-tools'\nimport { useViewerClipping } from '../presentation/useViewerClipping'\nimport { useCleanView } from './useCleanView'\nimport {\n DocumentLabelBar,\n PdfPageNav,\n ViewerControlBar,\n ViewerFrame,\n ViewerHeaderEnd,\n ViewerHeaderStart,\n ViewerImageActions,\n ViewerMessage,\n ViewerPageCounter,\n ViewerPane,\n ViewerStatusNote,\n ViewerTabBar,\n ViewerTitle,\n ViewerZoomControl,\n} from '../../files'\nimport { ErrorBoundary } from '../../components/ErrorBoundary'\nimport { fmtDate } from '../../lib/format'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { TabHeader } from '../../shell'\nimport { useConnectedWorkspace } from '../ConnectionProvider'\nimport { useConnectedConversations } from '../workspaceData'\nimport { ConnectedDocumentToolsProvider } from './ConnectedDocumentToolsProvider'\nimport { FinaliseTranslationButton } from './FinaliseTranslationButton'\nimport { useDocumentViewerSupport } from './support'\nimport { useImageCrop } from './useImageCrop'\nimport { ViewerCropModal } from './ViewerCropModal'\nimport { ViewerMoreMenu } from './ViewerMoreMenu'\nimport { useViewedDocument } from './useViewedDocument'\nimport { useViewerBlobs } from './useViewerBlobs'\nimport { useViewerTabs } from './useViewerTabs'\nimport { useViewerVersions } from './useViewerVersions'\nimport { VersionDropdown } from './VersionDropdown'\nimport { ParsedTextView } from './parsed/ParsedTextView'\nimport { ViewerPdfPane, type SignatureFlow } from './ViewerPdfPane'\n// The Word editor itself is its own chunk (`docxEditorChunk`), loaded when a Word document shows.\nimport { ConnectedNativeDocxEditor as NativeDocxEditor } from '../docx/ConnectedNativeDocxEditor'\nimport { canChangeVisibility } from '../../files/permissions'\nimport { SlidesTab } from './slidesTabChunk'\n\nconst StreamedWordArtifact = lazy(() =>\n import('../docx/ConnectedStreamedWordArtifact').then((m) => ({\n default: m.ConnectedStreamedWordArtifact,\n }))\n)\nconst NativeDocxComparison = lazy(() =>\n import('../docx/ConnectedNativeDocxComparison').then((m) => ({\n default: m.ConnectedNativeDocxComparison,\n }))\n)\n\nconst UPLOADED_NO_VERSIONS =\n 'No earlier versions yet. Replacing, editing or signing this file adds a new version here.'\n\nexport interface ConnectedDocumentViewerProps {\n /**\n * The document, or a version reference `doc-\u2026@v{n}` (a citation, a \"made from v2\" link): an\n * earlier version opens read-only. Default: the session state's viewing document.\n */\n documentId?: string\n /** Controls at the right end of the header (a panel's dock / pop-out switcher). */\n headerActions?: ReactNode\n /** Where html/react artifacts load their sandbox runtime from. */\n artifactRuntimeUrl?: string\n}\n\nexport function ConnectedDocumentViewer(props: ConnectedDocumentViewerProps) {\n const viewing = useArbiSessionState((s) => s.viewingDocument?.id)\n const openedId = props.documentId ?? viewing\n if (!openedId) return null\n // A viewer that throws (a PDF the browser cannot render, say) shows the error here, in the\n // viewer's place, instead of unmounting the whole app.\n return (\n <ErrorBoundary\n resetKey={openedId}\n labels={{ title: \"This document couldn't be displayed\" }}\n testId=\"document-viewer-error\"\n >\n <ConnectedDocumentToolsProvider>\n <DocumentViewerContent {...props} openedId={openedId} />\n </ConnectedDocumentToolsProvider>\n </ErrorBoundary>\n )\n}\n\nfunction DocumentViewerContent({\n openedId,\n headerActions,\n artifactRuntimeUrl = '/artifact-runtime/',\n}: ConnectedDocumentViewerProps & { openedId: string }) {\n const arbi = useArbi()\n const session = useArbiSessionStore()\n const support = useDocumentViewerSupport()\n const formatDate = support.formatDate ?? fmtDate\n const tools = useDocumentTools()\n const { openConversation, openNewConversation, notify } = useBlocksEnvironment()\n const { userId: currentUserId } = useConnectedWorkspace()\n // A document keeps one id for its whole life; its versions are inside it.\n const documentId = parseVersionRef(openedId).docId\n const [totalPages, setTotalPages] = useState<number>(0)\n const [isCompact, setIsCompact] = useState(false)\n // Zoom of the PDF (canvas scale) / text, as a multiplier of fit width; pinch, double-tap and the\n // zoom button all drive it. The text view's size is a reading preference for every document.\n const [pdfZoom, setPdfZoom] = useState(1)\n const {\n tab: zoomTab,\n textScale,\n compareId: compareDocumentId,\n } = useArbiSessionState((s) => s.documentViewer)\n const zoom = zoomTab === 'html' ? textScale : pdfZoom\n const setZoom = useCallback(\n (next: number | ((z: number) => number)) => {\n const value = typeof next === 'function' ? next(zoom) : next\n if (zoomTab === 'html') session.setDocumentViewer({ textScale: value })\n else setPdfZoom(value)\n },\n [zoomTab, session, zoom]\n )\n const [scrollTrigger, setScrollTrigger] = useState(0) // Incremented to scroll the viewers\n const containerRef = useRef<HTMLDivElement>(null)\n\n const viewingDocumentPage = useArbiSessionState((s) => s.viewingDocument?.page ?? null)\n const setViewingDocumentPage = (page: number) =>\n session.setViewingDocument({ id: openedId, page })\n const setViewingDocumentId = (id: string) => session.setViewingDocument({ id })\n const setActiveTab = (tab: Parameters<typeof session.setDocumentViewer>[0]['tab']) =>\n session.setDocumentViewer({ tab })\n const setCompareDocumentId = (id: string | null) => session.setDocumentViewer({ compareId: id })\n const { data: conversations } = useConnectedConversations()\n\n // An earlier version opened read-only (`doc-\u2026@v{n}`) from the Versions tab, a citation or a\n // \"made from\" link. Word documents show it in the Word editor, artifacts in theirs, everything\n // else as its PDF. The version on screen is the session's viewing id, not local state: the\n // viewer remounts when its panel moves to a new window, and the version must come along.\n const snapshotRef = parseVersionRef(openedId).version ? openedId : null\n // Every version of the document, oldest first. Every version of an artifact shares one name, so\n // both sides of a comparison get the timeline's \"v1/v2/v3\" label.\n const { versions, translations } = useViewerVersions(documentId)\n const currentVersionId = versions.find((v) => v.isCurrent)?.id ?? documentId\n // Opening the current version is the live document itself, not a read-only copy of it.\n const snapshotDocumentId = snapshotRef && snapshotRef !== currentVersionId ? snapshotRef : null\n const doc = useViewedDocument(documentId)\n const setSnapshotDocumentId = (ref: string | null) => setViewingDocumentId(ref ?? documentId)\n // Drafting mode: a thread bound to the open document (or the one it was made in) drafts in it,\n // also while an earlier version of it is on screen; a turn sent then brings the live document\n // back, where the assistant's edits appear. Being open binds no chat to it.\n useRegisterOpenDocument({\n documentId: doc.savedDocumentId,\n shownId: openedId,\n showLive: () => setViewingDocumentId(documentId),\n workspaceId: doc.workspaceId,\n conversationId: doc.documentData?.conversation_ext_id ?? null,\n })\n const {\n documentData,\n streamingDoc,\n isStreaming,\n draftDoc,\n isPresentation,\n isDraft,\n isCaptureDraft,\n labelSummaries,\n isImage,\n isVideo,\n isAudio,\n isMedia,\n isArtifact,\n liveKind,\n liveSource,\n isDocx,\n isXlsx,\n isDownloadOnly,\n } = doc\n // The thread bound to this document: its latest one, else a new chat bound to it. The document\n // stays on screen beside it.\n const chatAboutDocument = () => {\n const savedId = doc.savedDocumentId\n if (!savedId) return\n const latest = latestThreadOfDocument(conversations, savedId)\n if (latest) {\n openConversation(latest, { keepDocumentOpen: true })\n return\n }\n // Opening a new chat starts it unbound; it is bound after.\n openNewConversation({ keepDocumentOpen: true })\n session.setNewChatDocumentId(savedId)\n }\n // A thread by its title, for the threads a document (and each version) was made in.\n const threadTitle = (id: string) =>\n conversations.find((c) => c.external_id === id)?.title?.trim() || 'Its thread'\n // The thread a generated document was made in (none for an upload).\n const madeInId = documentData?.conversation_ext_id ?? null\n const madeIn = madeInId ? { id: madeInId, title: threadTitle(madeInId) } : null\n const pdfSnapshotId = snapshotDocumentId && (!isArtifact || isDocx) ? snapshotDocumentId : null\n // The document on screen: an earlier version when one is open, else the current one.\n const shownDocumentId = pdfSnapshotId || documentId\n const blobs = useViewerBlobs(shownDocumentId, doc)\n const [minimumPdfVersion, setMinimumPdfVersion] = useState<number | null>(null)\n useEffect(() => setMinimumPdfVersion(null), [documentId])\n const versionReady =\n !!pdfSnapshotId ||\n minimumPdfVersion === null ||\n (documentData?.current_version ?? 0) >= minimumPdfVersion\n const { xlsxBlob, xlsxError, handleDirectDownload } = blobs\n const pdfBlob = versionReady ? blobs.pdfBlob : null\n const pdfVerified = !!pdfBlob && blobs.pdfVerified !== false\n // Annotation mode for the PDF view; off for every newly opened document.\n const [annotating, setAnnotating] = useState(false)\n const [sharingFile, setSharingFile] = useState(false)\n useEffect(() => setAnnotating(false), [documentId])\n // My signature: one's saved signature or initials, to place as a picture stamp in the markup.\n const [placeMark, setPlaceMark] = useState<{ image: string; label: string; key: number } | null>(\n null\n )\n // Translations are listed with the versions (each is its own document), so they open the tab too.\n const hasHistory =\n versions.length > 1 || (documentData?.current_version ?? 1) > 1 || translations.length > 0\n const {\n activeTab,\n handleTabChange: changeTab,\n viewerTabs,\n } = useViewerTabs(doc, isCompact, hasHistory)\n const saveWordRef = useRef<(() => Promise<boolean | number>) | null>(null)\n const transitionPending = useRef(false)\n const transitionKey = JSON.stringify([openedId, doc.workspaceId])\n const transitionScope = useRef({ key: transitionKey, generation: 0 })\n if (transitionScope.current.key !== transitionKey) {\n transitionScope.current = {\n key: transitionKey,\n generation: transitionScope.current.generation + 1,\n }\n }\n useEffect(\n () => () => {\n transitionScope.current.generation += 1\n },\n []\n )\n const requestViewerTransition = async (transition: () => void): Promise<boolean> => {\n if (transitionPending.current) return false\n const leavingWord =\n isDocx &&\n !isDraft &&\n !isStreaming &&\n !snapshotDocumentId &&\n (activeTab === 'docx' || (isArtifact && !liveKind && activeTab === 'edit'))\n if (leavingWord) {\n transitionPending.current = true\n const generation = transitionScope.current.generation\n try {\n const saved = saveWordRef.current && (await saveWordRef.current())\n if (!saved) {\n notify('Could not save the current document. Stay in the editor and try again.', 'error')\n return false\n }\n if (generation !== transitionScope.current.generation) return false\n if (typeof saved === 'number') setMinimumPdfVersion(saved)\n } finally {\n transitionPending.current = false\n }\n }\n transition()\n return true\n }\n const handleTabChange = (tab: string) => {\n if (tab === activeTab) return\n void requestViewerTransition(() => changeTab(tab))\n }\n const crop = useImageCrop(\n documentId,\n documentData?.file_name,\n pdfBlob,\n documentData?.workspace_ext_id\n )\n // Signing: choose where the signature goes (placing), then the Sign dialog.\n const [placingSignature, setPlacingSignature] = useState(false)\n const [signAppearance, setSignAppearance] = useState<SignatureAppearance | undefined>()\n const [isSignOpen, setIsSignOpen] = useState(false)\n const signingScope = JSON.stringify([\n documentId,\n snapshotDocumentId,\n documentData?.current_version,\n ])\n const signingScopeRef = useRef(signingScope)\n const signingScopeMatches = signingScopeRef.current === signingScope\n // Leaving the placement when another version opens or returns: it belongs to the copy on screen.\n useEffect(() => {\n setPlacingSignature(false)\n setIsSignOpen(false)\n setSignAppearance(undefined)\n signingScopeRef.current = signingScope\n }, [signingScope])\n // A signature request: the author placing fields ('prepare'), or a signer walked through theirs.\n const [signatureFlow, setSignatureFlow] = useState<SignatureFlow>(null)\n useEffect(() => setSignatureFlow(null), [signingScope])\n const signatureDocumentId =\n pdfSnapshotId ||\n (documentData?.current_version ? `${documentId}@v${documentData.current_version}` : documentId)\n const { data: signatureStatus } = useDocumentSignatures(\n signatureDocumentId,\n !isDraft && !liveKind\n )\n\n // The Word editor on the current version: the editor's own ribbon says \"Co-edit mode\", so the\n // header carries no version label and, when narrow, no title row above the ribbon.\n const isCoEditing =\n !snapshotDocumentId &&\n !compareDocumentId &&\n !isDraft &&\n ((activeTab === 'docx' && isDocx) ||\n (activeTab === 'slides' && isPresentation) ||\n (activeTab === 'edit' && isArtifact && !liveKind && !isStreaming))\n const currentVersionLabel = isCoEditing\n ? undefined\n : !snapshotDocumentId && !compareDocumentId && (isDocx || (isArtifact && !liveKind))\n ? 'Live'\n : versionLabel(versions, snapshotDocumentId || documentId)\n const compareVersionLabel = versionLabel(versions, compareDocumentId)\n const snapshotNumber = findVersion(versions, snapshotDocumentId)?.number\n // The markup of the version on screen: the default view when it has any (\"Show original\" hides).\n const pdfSnapshotNumber = pdfSnapshotId\n ? (parseVersionRef(pdfSnapshotId).version ?? undefined)\n : undefined\n // A signed version is locked: only a further signature changes it. Its marks stay in the markup\n // layer (never in its PDF), and editing its content saves a new, unsigned version.\n const isSigned = !!signatureStatus?.signed\n const markup = useDocumentMarkup(documentData, pdfSnapshotNumber, isSigned)\n\n // Detect container width changes (640px = the sm: breakpoint).\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) setIsCompact(entry.contentRect.width < 640)\n })\n resizeObserver.observe(container)\n return () => resizeObserver.disconnect()\n }, [])\n\n const handleLoadSuccess = useCallback((numPages: number) => setTotalPages(numPages), [])\n\n // Go to a page: the counter, or one step from the arrows.\n const goToPage = (page: number) => {\n setViewingDocumentPage(page)\n setScrollTrigger((prev) => prev + 1)\n }\n const stepPage = (delta: number) => {\n const next = (viewingDocumentPage || 1) + delta\n if (next >= 1 && next <= totalPages) goToPage(next)\n }\n\n const documentTitle =\n streamingDoc?.title ||\n draftDoc?.title ||\n documentData?.doc_metadata?.title ||\n documentData?.file_name ||\n 'Document'\n\n // The page / zoom controls, shared by the PDF and the text view. They sit in the control bar\n // under the body, so they never cover the text being read.\n const pageNav = totalPages > 0 && (\n <>\n <ViewerZoomControl zoom={zoom} onCycle={() => setZoom(cycleZoom(zoom))} />\n <PdfPageNav\n canPrev={(viewingDocumentPage || 1) > 1}\n canNext={(viewingDocumentPage || 1) < totalPages}\n onPrev={() => stepPage(-1)}\n onNext={() => stepPage(1)}\n counter={\n <ViewerPageCounter page={viewingDocumentPage || 1} total={totalPages} onGoTo={goToPage} />\n }\n />\n </>\n )\n\n // Compare: a \"Compare vs. [doc]\" row of its own below the tab/title bar (a docked panel is\n // narrow), with the flip-direction arrow and the way out.\n const isComparing = !!compareDocumentId\n const compareTarget = compareDocumentId ? parseVersionRef(compareDocumentId).docId : null\n const compareIndicator = isComparing && compareTarget && (\n <ArtifactCompareBar\n compareTarget={support.renderDocumentPill?.(compareTarget) ?? compareTarget}\n versionLabel={compareVersionLabel}\n mode=\"flip\"\n showTrackChanges={false}\n onToggleTrackChanges={() => {}}\n onFlip={() => {\n setViewingDocumentId(compareDocumentId!)\n setCompareDocumentId(documentId)\n }}\n onStop={() => setCompareDocumentId(null)}\n />\n )\n\n // Document name block: the name, related documents and status notes. Roomy headers keep it on\n // the tab row; a narrow (phone / docked) header gives it a row of its own so the name is never\n // cut down to a couple of letters by the tabs and actions.\n const titleBlock = (\n <>\n {/* A draft gets an editable name + auto-name toggle instead of the plain read-only name. */}\n {isDraft ? (\n <ViewerDraftTitle documentId={documentId} />\n ) : (\n <ViewerTitle\n title={documentTitle}\n versionLabel={currentVersionLabel}\n shrink={!!liveKind || isCompact}\n />\n )}\n {/* The narrow header's Share is icon-only, so the state is spelled out here as text. */}\n {isCompact && !isDraft && documentData?.shared && (\n <SharingEntity shared variant=\"icon\" data-testid=\"document-shared-status\" />\n )}\n {/* Likewise \"Show original\" is a bare page icon there: say which view is on screen. */}\n {isCompact &&\n activeTab === 'pdf' &&\n pdfBlob &&\n markup.hasMarkup &&\n !annotating &&\n !placingSignature && (\n <MarkupViewNote\n showOriginal={markup.showOriginal}\n onToggle={() => markup.setShowOriginal((on) => !on)}\n />\n )}\n {/* Related documents, except during a comparison (its own row says which). */}\n {!isComparing && !liveKind && documentData && (\n <ViewerRelatedDocuments document={documentData} />\n )}\n {isStreaming && <ViewerStatusNote pulse>streaming...</ViewerStatusNote>}\n {/* Nothing is generating: this document simply does not exist on the backend yet. */}\n {isDraft && (\n <ViewerStatusNote testId=\"draft-unsaved-indicator\">Draft \u2014 not saved</ViewerStatusNote>\n )}\n {signatureStatus?.signed && (\n <SignatureStatus status={signatureStatus} formatDate={formatDate} />\n )}\n </>\n )\n\n const leftContent = (\n <ViewerHeaderStart>\n {isDraft ? (\n // A draft's kind replaces the tabs: neither Versions nor the text view means anything\n // before the first save.\n <ViewerDraftKind documentId={documentId} />\n ) : (\n <>\n <ViewerTabBar\n tabs={viewerTabs.filter((tab) => tab.id !== 'versions')}\n activeId={activeTab}\n onChange={handleTabChange}\n />\n {(isArtifact || isDocx || hasHistory) && !liveKind && !isComparing && (\n <VersionDropdown\n versions={versions}\n activeId={\n snapshotDocumentId ??\n (currentVersionId === documentId && documentData?.current_version\n ? `${documentId}@v${documentData.current_version}`\n : currentVersionId)\n }\n isSnapshot={!!snapshotDocumentId}\n onOpen={(id) => {\n void requestViewerTransition(() => {\n setSnapshotDocumentId(id === currentVersionId ? null : id)\n if (activeTab === 'versions')\n setActiveTab(isArtifact ? 'edit' : isDocx ? 'docx' : 'pdf')\n })\n }}\n onHistory={() => handleTabChange('versions')}\n />\n )}\n </>\n )}\n {!isCompact && titleBlock}\n </ViewerHeaderStart>\n )\n\n const annotatable = canAnnotate({\n activeTab,\n hasPdf: pdfVerified,\n isImage,\n isVideo,\n isAudio,\n isDownloadOnly,\n isDraft,\n isStreaming,\n isSnapshot: !!snapshotDocumentId,\n isComparing,\n })\n const clip = useViewerClipping(annotatable || (!!pdfBlob && (isImage || isVideo)), isCompact)\n const clean = useCleanView(clip.layer)\n\n // A request waiting for this user's signature, or their own in flight: shown over the PDF and\n // the Word editor alike; signing happens on the PDF.\n const signatureBanner = !isDraft && !liveKind && !snapshotDocumentId && (\n <SignatureRequestBanner\n documentId={documentId}\n hidden={!!signatureFlow}\n onSign={(request) => {\n void requestViewerTransition(() => {\n setAnnotating(false)\n setPlacingSignature(false)\n if (activeTab !== 'pdf') changeTab('pdf')\n setSignatureFlow({ kind: 'sign', request })\n })\n }}\n onEditDraft={(draft) => {\n void requestViewerTransition(() => {\n if (activeTab !== 'pdf') changeTab('pdf')\n setSignatureFlow({ kind: 'prepare', draft })\n })\n }}\n />\n )\n\n const share = () => {\n const name = (liveKind ? documentTitle : documentData?.file_name) || undefined\n if (support.share) {\n support.share({ id: documentId, name, isPrivate: !documentData?.shared })\n return\n }\n void arbi.documents\n .update([{ external_id: documentId, shared: !documentData?.shared }])\n .then(() => tools.onDocumentsChanged?.([documentId], 'markup'))\n .catch(() => notify(\"Couldn't change who can see this document\", 'error'))\n }\n const shownRef = snapshotDocumentId || documentId\n\n const rightContent = (\n <ViewerHeaderEnd isCompact={isCompact}>\n {/* Annotate: only for a PDF on screen (text and Word files are shown as a PDF too). Marks\n sit in a layer beside the document; Freeze saves a separate copy with them built in. */}\n {annotatable && (\n <AnnotateButton\n active={annotating}\n compact={isCompact}\n onClick={() => {\n setPlacingSignature(false)\n clip.stop()\n markup.setShowOriginal(false)\n setAnnotating((on) => !on)\n }}\n />\n )}\n {clip.button}\n {/* The markup is the default view; \"Show original\" shows the untouched file. */}\n {activeTab === 'pdf' && pdfBlob && !placingSignature && (markup.hasMarkup || annotating) && (\n <ShowOriginalButton\n active={markup.showOriginal}\n compact={isCompact}\n onClick={() => {\n setAnnotating(false)\n markup.setShowOriginal((on) => !on)\n }}\n />\n )}\n {activeTab === 'pdf' && markup.hasMarkup && !annotating && (\n <DownloadMarkupButton\n onClick={() => void markup.downloadMarkup()}\n // A signed version is locked: Download serves the signed file as it is.\n disabledReason={isSigned ? SIGNED_LOCKED_REASON : undefined}\n />\n )}\n {/* Image actions: start a generation from this image, or crop it into a new document. */}\n {activeTab === 'pdf' && isImage && pdfBlob && (\n <ViewerImageActions\n compact={isCompact}\n onUseAsReference={\n support.useImageAsReference ? () => support.useImageAsReference!(documentId) : undefined\n }\n onCrop={crop.handleOpenCrop}\n />\n )}\n {/* The thread it was made in: open it at the answer that made it. */}\n {madeIn && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size={isCompact ? 'icon' : 'sm'}\n onClick={() =>\n openConversation(madeIn.id, {\n messageId: documentData?.source_message_ext_id ?? undefined,\n })\n }\n title={`Open the thread it was made in: ${madeIn.title}`}\n aria-label={`Open the thread it was made in: ${madeIn.title}`}\n data-testid=\"document-open-thread\"\n >\n <MessageSquare className=\"size-4\" />\n {!isCompact && <span className=\"max-w-[10rem] truncate\">{madeIn.title}</span>}\n </Button>\n )}\n {documentId && documentData && !isDraft && !isStreaming && (\n <>\n <FileShareDialog\n open={sharingFile}\n onOpenChange={setSharingFile}\n documentId={documentId}\n version={pdfSnapshotNumber ?? documentData.current_version ?? 1}\n />\n </>\n )}\n {/* Chat about this document: the thread bound to it (its questions edit it), the latest one\n or a new one. Only such a thread drafts in a document: one merely open binds no chat. */}\n {doc.savedDocumentId && !snapshotDocumentId && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size={isCompact ? 'icon' : 'sm'}\n onClick={chatAboutDocument}\n title=\"Chat about this document: a thread that works in it, with edits as tracked changes\"\n aria-label=\"Chat about this document\"\n data-testid=\"document-chat-about\"\n className=\"pointer-coarse:min-h-11\"\n >\n <MessageSquarePlus className=\"size-4\" />\n {!isCompact && <span className=\"ml-1\">Chat</span>}\n </Button>\n )}\n {/* Share always asks first (the host's share dialog), so a click never changes who can see\n the file by surprise. */}\n {documentId && doc.workspaceId && (\n <ShareControl\n state={documentData?.shared ? 'shared' : 'private'}\n onToggle={share}\n disabled={!canChangeVisibility(documentData, currentUserId)}\n disabledTooltip=\"Only the owner can change visibility\"\n tooltip={\n documentData?.shared\n ? 'Shared with the workspace \u2014 click to share with specific people'\n : 'Share with the workspace, then optionally notify specific people by email'\n }\n variant=\"outline\"\n compact={isCompact}\n showState={!isCompact}\n labels={{\n shared: getEntityLabel('WORKSPACE'),\n private: 'Only you',\n mixed: 'Partly shared',\n }}\n testId=\"share-document-button\"\n stateTestId=\"document-title-shared-indicator\"\n />\n )}\n {/* Finalise (a translation): its current version saved as a new labelled PDF. */}\n {!isStreaming && !snapshotDocumentId && (\n <FinaliseTranslationButton document={documentData ?? undefined} isCompact={isCompact} />\n )}\n {/* Every signing action starts in one menu: sign yourself, save/place a mark, or request\n signatures from others. */}\n {annotatable && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant={\n placingSignature || signatureFlow?.kind === 'prepare' ? 'default' : 'outline'\n }\n size={isCompact ? 'icon' : 'sm'}\n aria-label=\"Sign\"\n title=\"Sign or request signatures\"\n data-testid=\"signing-menu-trigger\"\n className=\"pointer-coarse:min-h-11\"\n >\n <Signature className=\"size-4\" />\n {!isCompact && <span className=\"ml-1\">Sign</span>}\n <ChevronDown className=\"ml-1 size-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" forceMount>\n <DropdownMenuItem\n data-testid=\"sign-document-button\"\n onSelect={() => {\n setAnnotating(false)\n if (isSigned) {\n setSignatureFlow(null)\n setPlacingSignature((on) => !on)\n } else {\n setPlacingSignature(false)\n setSignatureFlow({ kind: 'prepare', self: true })\n }\n }}\n >\n <PenLine className=\"mr-2 size-4\" /> Sign this document\n </DropdownMenuItem>\n {!isSigned && (\n <>\n <PlaceMySignatureMenuItems\n onPlace={(mark) => {\n setPlacingSignature(false)\n setSignatureFlow(null)\n markup.setShowOriginal(false)\n setAnnotating(true)\n setPlaceMark({ ...mark, key: Date.now() })\n }}\n />\n <DropdownMenuItem\n data-testid=\"request-signatures-button\"\n onSelect={() => {\n setAnnotating(false)\n setPlacingSignature(false)\n setSignatureFlow(signatureFlow?.kind === 'prepare' ? null : { kind: 'prepare' })\n }}\n >\n <Users className=\"mr-2 size-4\" /> Ask someone to sign\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {isSignOpen && pdfBlob && pdfVerified && signingScopeMatches && (\n <SignDocumentDialog\n open={isSignOpen}\n onOpenChange={setIsSignOpen}\n documentId={documentId}\n pdfBlob={pdfBlob}\n // The PDF on screen is the current version's (an earlier one cannot be signed): the\n // server refuses if another version has landed since.\n version={documentData?.current_version ?? undefined}\n appearance={signAppearance}\n />\n )}\n <ViewerMoreMenu\n compact={isCompact}\n items={[\n ...(documentId && documentData && !isDraft && !isStreaming\n ? [\n {\n key: 'share-file',\n label: 'Share file\u2026',\n icon: <Link2 className=\"size-4\" />,\n description: 'Send a link to this version of the file',\n onSelect: () => setSharingFile(true),\n testId: 'share-file-button',\n },\n ]\n : []),\n ...(tools.emailDocument && !isDraft && !isStreaming && documentData?.file_name\n ? [\n {\n key: 'email',\n label: 'Email\u2026',\n icon: <Mail className=\"size-4\" />,\n description: 'Email this document (attached)',\n onSelect: () => tools.emailDocument?.(shownRef),\n testId: 'email-document-button',\n },\n ]\n : []),\n ...(support.translate &&\n !isDraft &&\n !isStreaming &&\n !liveKind &&\n !isImage &&\n documentData?.file_name\n ? [\n {\n key: 'translate',\n label: 'Translate\u2026',\n icon: <Languages className=\"size-4\" />,\n description: 'A new editable document, original and translation side by side',\n onSelect: () => support.translate!(shownRef),\n testId: 'translate-document-button',\n },\n ]\n : []),\n ]}\n />\n {headerActions}\n </ViewerHeaderEnd>\n )\n\n const viewerProps = {\n currentPage: viewingDocumentPage || undefined,\n onLoadSuccess: handleLoadSuccess,\n scrollTrigger,\n zoom,\n onZoomChange: setZoom,\n }\n\n return (\n <ViewerFrame\n frameRef={containerRef}\n contentId={documentId}\n header={\n <>\n <TabHeader\n tabs={[]}\n activeTabId={activeTab}\n onTabChange={handleTabChange}\n leftContent={leftContent}\n rightContent={rightContent}\n variant=\"underline\"\n />\n {isCompact && !isCoEditing && (\n <div data-slot=\"viewer-title-row\" className=\"flex min-w-0 items-center gap-2 px-3 pb-2\">\n {titleBlock}\n </div>\n )}\n {/* In the sticky header, not the content area: the PDF view scrolls its first page into\n view, which scrolls a bar above it out of sight. */}\n {snapshotDocumentId && (\n <VersionSnapshotBar\n versionNumber={snapshotNumber}\n live={isDocx || isArtifact}\n onAsk={\n support.askAboutVersion\n ? () => support.askAboutVersion!(snapshotDocumentId)\n : undefined\n }\n onReturn={() => setSnapshotDocumentId(null)}\n />\n )}\n </>\n }\n compareRow={isComparing ? compareIndicator || undefined : undefined}\n {...clean.frame}\n footer={<ViewerCropModal crop={crop} />}\n >\n {isComparing && (\n <Suspense fallback={<ViewerMessage>Loading comparison\u2026</ViewerMessage>}>\n <NativeDocxComparison\n baseId={compareDocumentId!}\n revisedId={documentId}\n title={documentTitle}\n />\n </Suspense>\n )}\n {/* A capture draft (photo/video/audio) has no backend document at all until it is saved:\n its recorder takes over the whole content area. */}\n {isCaptureDraft && <ViewerCaptureDraft documentId={documentId} />}\n\n {/* Media stay mounted (hidden) on the text tab, so playback goes on while reading the\n transcript. */}\n {!isCaptureDraft &&\n (activeTab === 'pdf' || (isMedia && activeTab === 'html')) &&\n (!isArtifact || (isDocx && !isDraft && !isStreaming && !liveKind)) &&\n !isComparing && (\n <ViewerPane hidden={activeTab !== 'pdf'}>\n {/* The labels are the document's, whichever view it is read in: the PDF gets the\n chips without the passage stepper (no parsed passages to walk here). */}\n {!clean.on && <DocumentLabelBar summaries={labelSummaries} />}\n {!clean.on && !isMedia && !isImage && signatureBanner}\n {!clean.on && activeTab === 'pdf' && pdfBlob && !pdfVerified && (\n <ViewerMessage>\n Offline copy: its version cannot be verified. Reconnect before signing.{' '}\n <button type=\"button\" onClick={() => void blobs.retryPdf()} className=\"underline\">\n Retry loading the current PDF\n </button>\n </ViewerMessage>\n )}\n {!clean.on && activeTab === 'pdf' && !isMedia && !isImage && (\n <MarkupNotices\n legacyPrompt={markup.legacyPrompt}\n olderNote={markup.olderNote}\n onOpenVersion={(n) => setSnapshotDocumentId(`${documentId}@v${n}`)}\n />\n )}\n <ViewerControlBar controls={!clean.on && activeTab === 'pdf' && pageNav}>\n <ViewerPdfPane\n documentId={documentId}\n doc={doc}\n pdfBlob={pdfBlob}\n isPdfLoading={!versionReady || blobs.isPdfLoading}\n pdfError={blobs.pdfError}\n onDownload={() => void handleDirectDownload()}\n viewerProps={viewerProps}\n signatureFlow={pdfVerified && signingScopeMatches ? signatureFlow : null}\n onSignatureFlow={setSignatureFlow}\n currentUserId={currentUserId}\n placingSignature={pdfVerified && signingScopeMatches && placingSignature}\n onPlacingDone={(appearance) => {\n setPlacingSignature(false)\n if (!appearance) return\n setSignAppearance(appearance)\n setIsSignOpen(true)\n }}\n annotating={annotating}\n clipping={clip.clipping}\n markup={markup}\n pdfSnapshotNumber={pdfSnapshotNumber}\n isSigned={isSigned}\n placeMark={placeMark}\n />\n </ViewerControlBar>\n </ViewerPane>\n )}\n\n {activeTab === 'preview' && isArtifact && liveKind && (\n // The preview loads its JSX compiler on first use, so it stays out of the main bundle.\n <ArtifactPreview\n kind={liveKind}\n source={liveSource}\n isStreaming={isStreaming}\n runtimeUrl={artifactRuntimeUrl}\n />\n )}\n\n {activeTab === 'edit' && isArtifact && liveKind && (\n <ArtifactCodeView source={liveSource} fileName={documentData?.file_name ?? undefined} />\n )}\n\n {/* A document draft is stored as DOCX: once generation ends the Word editor opens the stored\n document. Only a draft still being generated shows the streamed preview. */}\n {activeTab === 'edit' && isArtifact && !liveKind && !isStreaming && !isComparing && (\n <Suspense fallback={<ViewerMessage>Loading editor\u2026</ViewerMessage>}>\n {isSigned && !snapshotDocumentId && <SignedEditNote />}\n <NativeDocxEditor\n key={`${snapshotDocumentId || documentId}-${snapshotDocumentId ? 'snapshot' : 'live'}`}\n documentId={snapshotDocumentId || documentId}\n title={documentTitle}\n draftContent={isDraft ? draftDoc?.content || '' : undefined}\n snapshot={!!snapshotDocumentId}\n saveRef={saveWordRef}\n onSaved={(id) => {\n if (!isDraft) return\n session.clearDraftDocument(documentId)\n setViewingDocumentId(id)\n }}\n />\n </Suspense>\n )}\n\n {activeTab === 'versions' && (isArtifact || isDocx || hasHistory) && !isComparing && (\n <VersionTimeline\n // Each version made in a thread names it and opens it at the turn that made it.\n versions={versions.map((v) => ({\n ...v,\n madeIn: v.thread\n ? {\n label: threadTitle(v.thread.conversationId),\n onOpen: () =>\n openConversation(v.thread!.conversationId, {\n messageId: v.thread!.messageId ?? undefined,\n }),\n }\n : null,\n }))}\n currentId={currentVersionId}\n live={!!liveKind}\n // An uploaded file is not a draft: its versions come from replacing, editing or signing.\n labels={isArtifact ? undefined : { emptyDocument: UPLOADED_NO_VERSIONS }}\n formatDate={formatDate}\n onOpen={(id) => {\n // The current version is the live document itself, not a read-only copy of it.\n setSnapshotDocumentId(id === currentVersionId ? null : id)\n setActiveTab(isArtifact ? 'edit' : isDocx ? 'docx' : 'pdf')\n }}\n onCompare={(id) => session.setDocumentViewer({ compareId: id, tab: 'html' })}\n translations={translations}\n onOpenTranslation={(id) => setViewingDocumentId(id)}\n />\n )}\n\n {activeTab === 'xlsx' &&\n isXlsx &&\n (xlsxBlob ? (\n <XlsxViewer blob={xlsxBlob} />\n ) : (\n <ViewerMessage>\n {xlsxError ? 'Failed to load spreadsheet' : 'Loading spreadsheet...'}\n </ViewerMessage>\n ))}\n\n {activeTab === 'slides' && isPresentation && (\n <Suspense fallback={<ViewerMessage>Loading slides\u2026</ViewerMessage>}>\n <SlidesTab\n documentId={documentId}\n version={snapshotDocumentId ? snapshotNumber : undefined}\n currentVersion={documentData?.current_version ?? undefined}\n draftTitle={isDraft ? (draftDoc?.title ?? '') : undefined}\n />\n </Suspense>\n )}\n {activeTab === 'docx' && isDocx && !isComparing && (\n <Suspense fallback={<ViewerMessage>Loading editor\u2026</ViewerMessage>}>\n {signatureBanner}\n {isSigned && !snapshotDocumentId && <SignedEditNote />}\n <NativeDocxEditor\n key={`${snapshotDocumentId || documentId}-${snapshotDocumentId ? 'snapshot' : 'live'}`}\n documentId={snapshotDocumentId || documentId}\n title={documentTitle}\n snapshot={!!snapshotDocumentId}\n saveRef={saveWordRef}\n />\n </Suspense>\n )}\n\n {streamingDoc &&\n isStreaming &&\n isArtifact &&\n !liveKind &&\n !isComparing &&\n (activeTab === 'html' || activeTab === 'edit') && (\n <Suspense fallback={<ViewerMessage>Opening draft\u2026</ViewerMessage>}>\n <StreamedWordArtifact\n key={documentId}\n documentId={documentId.startsWith('doc-') ? documentId : undefined}\n title={documentTitle}\n content={streamingDoc.content}\n busy={isStreaming}\n />\n </Suspense>\n )}\n\n {!isCaptureDraft &&\n !isComparing &&\n activeTab === 'html' &&\n !(isStreaming && isArtifact && !liveKind) && (\n <ViewerPane>\n <ViewerControlBar controls={pageNav}>\n <ParsedTextView\n documentId={pdfSnapshotId || documentId}\n onLoadSuccess={handleLoadSuccess}\n scrollTrigger={scrollTrigger}\n zoom={zoom}\n onZoomChange={setZoom}\n />\n </ViewerControlBar>\n </ViewerPane>\n )}\n </ViewerFrame>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * The whole document viewer on the signed-in session: a document (or one of its versions, read\n * only) as its PDF, its text, the Word editor, a sheet, an image, a recording or a live artifact;\n * its versions and comparisons; markup, signing and signature requests; sharing, Email, Translate\n * and Finalise. Runs under any host (`useConnectedWorkspace`): the open document, tab and comparison\n * are the session state's, navigation the `BlocksEnvironment`'s, and what only the host knows comes\n * as its host config's `viewer`.\n */\n\nimport { lazy, Suspense, useCallback, useEffect, useRef, useState, type ReactNode } from 'react'\nimport {\n ChevronDown,\n Languages,\n Link2,\n Mail,\n MessageSquare,\n MessageSquarePlus,\n PenLine,\n Signature,\n Users,\n} from 'lucide-react'\nimport { useArbi, useArbiSessionState, useArbiSessionStore } from '@arbidocs/react'\nimport { findVersion, parseVersionRef, versionLabel } from '@arbidocs/react/artifacts'\nimport {\n SIGNED_LOCKED_REASON,\n canAnnotate,\n useDocumentMarkup,\n useDocumentSignatures,\n useDocumentTools,\n type SignatureAppearance,\n} from '@arbidocs/react/document-tools'\nimport { XlsxViewer, cycleZoom } from '@arbidocs/react/viewers'\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n getEntityLabel,\n SharingEntity,\n} from '@arbidocs/react/ui'\nimport {\n ArtifactCodeView,\n ArtifactCompareBar,\n ArtifactPreview,\n VersionTimeline,\n} from '../../artifacts'\nimport { latestThreadOfDocument, useRegisterOpenDocument } from '@arbidocs/react/shell'\nimport { ShareControl } from '../../collaboration/sharing/ShareControl'\nimport {\n ViewerCaptureDraft,\n ViewerDraftKind,\n ViewerDraftTitle,\n ViewerRelatedDocuments,\n} from './drafts'\nimport {\n AnnotateButton,\n DownloadMarkupButton,\n FileShareDialog,\n MarkupNotices,\n MarkupViewNote,\n PlaceMySignatureMenuItems,\n ShowOriginalButton,\n SignDocumentDialog,\n SignedEditNote,\n SignatureRequestBanner,\n SignatureStatus,\n VersionSnapshotBar,\n} from '../../document-tools'\nimport { useViewerClipping } from '../presentation/useViewerClipping'\nimport { useCleanView } from './useCleanView'\nimport {\n DocumentLabelBar,\n PdfPageNav,\n ViewerControlBar,\n ViewerFrame,\n ViewerHeaderEnd,\n ViewerHeaderStart,\n ViewerImageActions,\n ViewerMessage,\n ViewerPageCounter,\n ViewerPane,\n ViewerStatusNote,\n ViewerTabBar,\n ViewerTitle,\n ViewerZoomControl,\n} from '../../files'\nimport { ErrorBoundary } from '../../components/ErrorBoundary'\nimport { fmtDate } from '../../lib/format'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { TabHeader } from '../../shell'\nimport { useConnectedWorkspace } from '../ConnectionProvider'\nimport { useConnectedConversations } from '../workspaceData'\nimport { ConnectedDocumentToolsProvider } from './ConnectedDocumentToolsProvider'\nimport { FinaliseTranslationButton } from './FinaliseTranslationButton'\nimport { useDocumentViewerSupport } from './support'\nimport { useImageCrop } from './useImageCrop'\nimport { ViewerCropModal } from './ViewerCropModal'\nimport { ViewerMoreMenu } from './ViewerMoreMenu'\nimport { useViewedDocument } from './useViewedDocument'\nimport { useViewerBlobs } from './useViewerBlobs'\nimport { useViewerTabs } from './useViewerTabs'\nimport { useViewerVersions } from './useViewerVersions'\nimport { VersionDropdown } from './VersionDropdown'\nimport { ParsedTextView } from './parsed/ParsedTextView'\nimport { ViewerPdfPane, type SignatureFlow } from './ViewerPdfPane'\n// The Word editor itself is its own chunk (`docxEditorChunk`), loaded when a Word document shows.\nimport { ConnectedNativeDocxEditor as NativeDocxEditor } from '../docx/ConnectedNativeDocxEditor'\nimport { canChangeVisibility } from '../../files/permissions'\nimport { SlidesTab } from './slidesTabChunk'\n\nconst StreamedWordArtifact = lazy(() =>\n import('../docx/ConnectedStreamedWordArtifact').then((m) => ({\n default: m.ConnectedStreamedWordArtifact,\n }))\n)\nconst NativeDocxComparison = lazy(() =>\n import('../docx/ConnectedNativeDocxComparison').then((m) => ({\n default: m.ConnectedNativeDocxComparison,\n }))\n)\n\nconst UPLOADED_NO_VERSIONS =\n 'No earlier versions yet. Replacing, editing or signing this file adds a new version here.'\n\nexport interface ConnectedDocumentViewerProps {\n /**\n * The document, or a version reference `doc-\u2026@v{n}` (a citation, a \"made from v2\" link): an\n * earlier version opens read-only. Default: the session state's viewing document.\n */\n documentId?: string\n /** Controls at the right end of the header (a panel's dock / pop-out switcher). */\n headerActions?: ReactNode\n /** Where html/react artifacts load their sandbox runtime from. */\n artifactRuntimeUrl?: string\n}\n\nexport function ConnectedDocumentViewer(props: ConnectedDocumentViewerProps) {\n const viewing = useArbiSessionState((s) => s.viewingDocument?.id)\n const openedId = props.documentId ?? viewing\n if (!openedId) return null\n // A viewer that throws (a PDF the browser cannot render, say) shows the error here, in the\n // viewer's place, instead of unmounting the whole app.\n return (\n <ErrorBoundary\n resetKey={openedId}\n labels={{ title: \"This document couldn't be displayed\" }}\n testId=\"document-viewer-error\"\n >\n <ConnectedDocumentToolsProvider>\n <DocumentViewerContent {...props} openedId={openedId} />\n </ConnectedDocumentToolsProvider>\n </ErrorBoundary>\n )\n}\n\nfunction DocumentViewerContent({\n openedId,\n headerActions,\n artifactRuntimeUrl = '/artifact-runtime/',\n}: ConnectedDocumentViewerProps & { openedId: string }) {\n const arbi = useArbi()\n const session = useArbiSessionStore()\n const support = useDocumentViewerSupport()\n const formatDate = support.formatDate ?? fmtDate\n const tools = useDocumentTools()\n const { openConversation, openNewConversation, notify } = useBlocksEnvironment()\n const { userId: currentUserId } = useConnectedWorkspace()\n // A document keeps one id for its whole life; its versions are inside it.\n const documentId = parseVersionRef(openedId).docId\n const [totalPages, setTotalPages] = useState<number>(0)\n const [isCompact, setIsCompact] = useState(false)\n // Zoom of the PDF (canvas scale) / text, as a multiplier of fit width; pinch, double-tap and the\n // zoom button all drive it. The text view's size is a reading preference for every document.\n const [pdfZoom, setPdfZoom] = useState(1)\n const {\n tab: zoomTab,\n textScale,\n compareId: compareDocumentId,\n } = useArbiSessionState((s) => s.documentViewer)\n const zoom = zoomTab === 'html' ? textScale : pdfZoom\n const setZoom = useCallback(\n (next: number | ((z: number) => number)) => {\n const value = typeof next === 'function' ? next(zoom) : next\n if (zoomTab === 'html') session.setDocumentViewer({ textScale: value })\n else setPdfZoom(value)\n },\n [zoomTab, session, zoom]\n )\n const [scrollTrigger, setScrollTrigger] = useState(0) // Incremented to scroll the viewers\n const containerRef = useRef<HTMLDivElement>(null)\n\n const viewingDocumentPage = useArbiSessionState((s) => s.viewingDocument?.page ?? null)\n const setViewingDocumentPage = (page: number) =>\n session.setViewingDocument({ id: openedId, page })\n const setViewingDocumentId = (id: string) => session.setViewingDocument({ id })\n const setActiveTab = (tab: Parameters<typeof session.setDocumentViewer>[0]['tab']) =>\n session.setDocumentViewer({ tab })\n const setCompareDocumentId = (id: string | null) => session.setDocumentViewer({ compareId: id })\n const { data: conversations } = useConnectedConversations()\n\n // An earlier version opened read-only (`doc-\u2026@v{n}`) from the Versions tab, a citation or a\n // \"made from\" link. Word documents show it in the Word editor, artifacts in theirs, everything\n // else as its PDF. The version on screen is the session's viewing id, not local state: the\n // viewer remounts when its panel moves to a new window, and the version must come along.\n const snapshotRef = parseVersionRef(openedId).version ? openedId : null\n // Every version of the document, oldest first. Every version of an artifact shares one name, so\n // both sides of a comparison get the timeline's \"v1/v2/v3\" label.\n const { versions, translations } = useViewerVersions(documentId)\n const currentVersionId = versions.find((v) => v.isCurrent)?.id ?? documentId\n // Opening the current version is the live document itself, not a read-only copy of it.\n const snapshotDocumentId = snapshotRef && snapshotRef !== currentVersionId ? snapshotRef : null\n const doc = useViewedDocument(documentId)\n const setSnapshotDocumentId = (ref: string | null) => setViewingDocumentId(ref ?? documentId)\n // Drafting mode: a thread bound to the open document (or the one it was made in) drafts in it,\n // also while an earlier version of it is on screen; a turn sent then brings the live document\n // back, where the assistant's edits appear. Being open binds no chat to it.\n useRegisterOpenDocument({\n documentId: doc.savedDocumentId,\n shownId: openedId,\n showLive: () => setViewingDocumentId(documentId),\n workspaceId: doc.workspaceId,\n conversationId: doc.documentData?.conversation_ext_id ?? null,\n })\n const {\n documentData,\n streamingDoc,\n isStreaming,\n draftDoc,\n isPresentation,\n isDraft,\n isCaptureDraft,\n labelSummaries,\n isImage,\n isVideo,\n isAudio,\n isMedia,\n isArtifact,\n liveKind,\n liveSource,\n isDocx,\n isXlsx,\n isDownloadOnly,\n } = doc\n // The thread bound to this document: its latest one, else a new chat bound to it. The document\n // stays on screen beside it.\n const chatAboutDocument = () => {\n const savedId = doc.savedDocumentId\n if (!savedId) return\n const latest = latestThreadOfDocument(conversations, savedId)\n if (latest) {\n openConversation(latest, { keepDocumentOpen: true })\n return\n }\n // Opening a new chat starts it unbound; it is bound after.\n openNewConversation({ keepDocumentOpen: true })\n session.setNewChatDocumentId(savedId)\n }\n // A thread by its title, for the threads a document (and each version) was made in.\n const threadTitle = (id: string) =>\n conversations.find((c) => c.external_id === id)?.title?.trim() || 'Its thread'\n // The thread a generated document was made in (none for an upload).\n const madeInId = documentData?.conversation_ext_id ?? null\n const madeIn = madeInId ? { id: madeInId, title: threadTitle(madeInId) } : null\n const pdfSnapshotId = snapshotDocumentId && (!isArtifact || isDocx) ? snapshotDocumentId : null\n // The document on screen: an earlier version when one is open, else the current one.\n const shownDocumentId = pdfSnapshotId || documentId\n const blobs = useViewerBlobs(shownDocumentId, doc)\n const [minimumPdfVersion, setMinimumPdfVersion] = useState<number | null>(null)\n useEffect(() => setMinimumPdfVersion(null), [documentId])\n const versionReady =\n !!pdfSnapshotId ||\n minimumPdfVersion === null ||\n (documentData?.current_version ?? 0) >= minimumPdfVersion\n const { xlsxBlob, xlsxError, handleDirectDownload } = blobs\n const pdfBlob = versionReady ? blobs.pdfBlob : null\n const pdfVerified = !!pdfBlob && blobs.pdfVerified !== false\n // Annotation mode for the PDF view; off for every newly opened document.\n const [annotating, setAnnotating] = useState(false)\n const [sharingFile, setSharingFile] = useState(false)\n useEffect(() => setAnnotating(false), [documentId])\n // My signature: one's saved signature or initials, to place as a picture stamp in the markup.\n const [placeMark, setPlaceMark] = useState<{ image: string; label: string; key: number } | null>(\n null\n )\n // Translations are listed with the versions (each is its own document), so they open the tab too.\n const hasHistory =\n versions.length > 1 || (documentData?.current_version ?? 1) > 1 || translations.length > 0\n const {\n activeTab,\n handleTabChange: changeTab,\n viewerTabs,\n } = useViewerTabs(doc, isCompact, hasHistory)\n const saveWordRef = useRef<(() => Promise<boolean | number>) | null>(null)\n const transitionPending = useRef(false)\n const transitionKey = JSON.stringify([openedId, doc.workspaceId])\n const transitionScope = useRef({ key: transitionKey, generation: 0 })\n if (transitionScope.current.key !== transitionKey) {\n transitionScope.current = {\n key: transitionKey,\n generation: transitionScope.current.generation + 1,\n }\n }\n useEffect(\n () => () => {\n transitionScope.current.generation += 1\n },\n []\n )\n const requestViewerTransition = async (transition: () => void): Promise<boolean> => {\n if (transitionPending.current) return false\n const leavingWord =\n isDocx &&\n !isDraft &&\n !isStreaming &&\n !snapshotDocumentId &&\n (activeTab === 'docx' || (isArtifact && !liveKind && activeTab === 'edit'))\n if (leavingWord) {\n transitionPending.current = true\n const generation = transitionScope.current.generation\n try {\n const saved = saveWordRef.current && (await saveWordRef.current())\n if (!saved) {\n notify('Could not save the current document. Stay in the editor and try again.', 'error')\n return false\n }\n if (generation !== transitionScope.current.generation) return false\n if (typeof saved === 'number') setMinimumPdfVersion(saved)\n } finally {\n transitionPending.current = false\n }\n }\n transition()\n return true\n }\n const handleTabChange = (tab: string) => {\n if (tab === activeTab) return\n void requestViewerTransition(() => changeTab(tab))\n }\n const crop = useImageCrop(\n documentId,\n documentData?.file_name,\n pdfBlob,\n documentData?.workspace_ext_id\n )\n // Signing: choose where the signature goes (placing), then the Sign dialog.\n const [placingSignature, setPlacingSignature] = useState(false)\n const [signAppearance, setSignAppearance] = useState<SignatureAppearance | undefined>()\n const [isSignOpen, setIsSignOpen] = useState(false)\n const signingScope = JSON.stringify([\n documentId,\n snapshotDocumentId,\n documentData?.current_version,\n ])\n const signingScopeRef = useRef(signingScope)\n const signingScopeMatches = signingScopeRef.current === signingScope\n // Leaving the placement when another version opens or returns: it belongs to the copy on screen.\n useEffect(() => {\n setPlacingSignature(false)\n setIsSignOpen(false)\n setSignAppearance(undefined)\n signingScopeRef.current = signingScope\n }, [signingScope])\n // A signature request: the author placing fields ('prepare'), or a signer walked through theirs.\n const [signatureFlow, setSignatureFlow] = useState<SignatureFlow>(null)\n useEffect(() => setSignatureFlow(null), [signingScope])\n const signatureDocumentId =\n pdfSnapshotId ||\n (documentData?.current_version ? `${documentId}@v${documentData.current_version}` : documentId)\n const { data: signatureStatus } = useDocumentSignatures(\n signatureDocumentId,\n !isDraft && !liveKind\n )\n\n // The Word editor on the current version: the editor's own ribbon says \"Co-edit mode\", so the\n // header carries no version label and, when narrow, no title row above the ribbon.\n const isCoEditing =\n !snapshotDocumentId &&\n !compareDocumentId &&\n !isDraft &&\n ((activeTab === 'docx' && isDocx) ||\n (activeTab === 'slides' && isPresentation) ||\n (activeTab === 'edit' && isArtifact && !liveKind && !isStreaming))\n const currentVersionLabel = isCoEditing\n ? undefined\n : !snapshotDocumentId && !compareDocumentId && (isDocx || (isArtifact && !liveKind))\n ? 'Live'\n : versionLabel(versions, snapshotDocumentId || documentId)\n const compareVersionLabel = versionLabel(versions, compareDocumentId)\n const snapshotNumber = findVersion(versions, snapshotDocumentId)?.number\n // The markup of the version on screen: the default view when it has any (\"Show original\" hides).\n const pdfSnapshotNumber = pdfSnapshotId\n ? (parseVersionRef(pdfSnapshotId).version ?? undefined)\n : undefined\n // A signed version is locked: only a further signature changes it. Its marks stay in the markup\n // layer (never in its PDF), and editing its content saves a new, unsigned version.\n const isSigned = !!signatureStatus?.signed\n const markup = useDocumentMarkup(documentData, pdfSnapshotNumber, isSigned)\n\n // Detect container width changes (640px = the sm: breakpoint).\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) setIsCompact(entry.contentRect.width < 640)\n })\n resizeObserver.observe(container)\n return () => resizeObserver.disconnect()\n }, [])\n\n const handleLoadSuccess = useCallback((numPages: number) => setTotalPages(numPages), [])\n\n // Go to a page: the counter, or one step from the arrows.\n const goToPage = (page: number) => {\n setViewingDocumentPage(page)\n setScrollTrigger((prev) => prev + 1)\n }\n const stepPage = (delta: number) => {\n const next = (viewingDocumentPage || 1) + delta\n if (next >= 1 && next <= totalPages) goToPage(next)\n }\n\n const documentTitle =\n streamingDoc?.title ||\n draftDoc?.title ||\n documentData?.doc_metadata?.title ||\n documentData?.file_name ||\n 'Document'\n\n // The page / zoom controls, shared by the PDF and the text view. They sit in the control bar\n // under the body, so they never cover the text being read.\n const pageNav = totalPages > 0 && (\n <>\n <ViewerZoomControl zoom={zoom} onCycle={() => setZoom(cycleZoom(zoom))} />\n <PdfPageNav\n canPrev={(viewingDocumentPage || 1) > 1}\n canNext={(viewingDocumentPage || 1) < totalPages}\n onPrev={() => stepPage(-1)}\n onNext={() => stepPage(1)}\n counter={\n <ViewerPageCounter page={viewingDocumentPage || 1} total={totalPages} onGoTo={goToPage} />\n }\n />\n </>\n )\n\n // Compare: a \"Compare vs. [doc]\" row of its own below the tab/title bar (a docked panel is\n // narrow), with the flip-direction arrow and the way out.\n const isComparing = !!compareDocumentId\n const compareTarget = compareDocumentId ? parseVersionRef(compareDocumentId).docId : null\n const compareIndicator = isComparing && compareTarget && (\n <ArtifactCompareBar\n compareTarget={support.renderDocumentPill?.(compareTarget) ?? compareTarget}\n versionLabel={compareVersionLabel}\n mode=\"flip\"\n showTrackChanges={false}\n onToggleTrackChanges={() => {}}\n onFlip={() => {\n setViewingDocumentId(compareDocumentId!)\n setCompareDocumentId(documentId)\n }}\n onStop={() => setCompareDocumentId(null)}\n />\n )\n\n // Document name block: the name, related documents and status notes. Roomy headers keep it on\n // the tab row; a narrow (phone / docked) header gives it a row of its own so the name is never\n // cut down to a couple of letters by the tabs and actions.\n const titleBlock = (\n <>\n {/* A draft gets an editable name + auto-name toggle instead of the plain read-only name. */}\n {isDraft ? (\n <ViewerDraftTitle documentId={documentId} />\n ) : (\n <ViewerTitle\n title={documentTitle}\n versionLabel={currentVersionLabel}\n shrink={!!liveKind || isCompact}\n />\n )}\n {/* The narrow header's Share is icon-only, so the state is spelled out here as text. */}\n {isCompact && !isDraft && documentData?.shared && (\n <SharingEntity shared variant=\"icon\" data-testid=\"document-shared-status\" />\n )}\n {/* Likewise \"Show original\" is a bare page icon there: say which view is on screen. */}\n {isCompact &&\n activeTab === 'pdf' &&\n pdfBlob &&\n markup.hasMarkup &&\n !annotating &&\n !placingSignature && (\n <MarkupViewNote\n showOriginal={markup.showOriginal}\n onToggle={() => markup.setShowOriginal((on) => !on)}\n />\n )}\n {/* Related documents, except during a comparison (its own row says which). */}\n {!isComparing && !liveKind && documentData && (\n <ViewerRelatedDocuments document={documentData} />\n )}\n {isStreaming && <ViewerStatusNote pulse>streaming...</ViewerStatusNote>}\n {/* Nothing is generating: this document simply does not exist on the backend yet. */}\n {isDraft && (\n <ViewerStatusNote testId=\"draft-unsaved-indicator\">Draft \u2014 not saved</ViewerStatusNote>\n )}\n {signatureStatus?.signed && (\n <SignatureStatus status={signatureStatus} formatDate={formatDate} />\n )}\n </>\n )\n\n const leftContent = (\n <ViewerHeaderStart>\n {isDraft ? (\n // A draft's kind replaces the tabs: neither Versions nor the text view means anything\n // before the first save.\n <ViewerDraftKind documentId={documentId} />\n ) : (\n <>\n <ViewerTabBar\n tabs={viewerTabs.filter((tab) => tab.id !== 'versions')}\n activeId={activeTab}\n onChange={handleTabChange}\n />\n {(isArtifact || isDocx || hasHistory) && !liveKind && !isComparing && (\n <VersionDropdown\n versions={versions}\n activeId={\n snapshotDocumentId ??\n (currentVersionId === documentId && documentData?.current_version\n ? `${documentId}@v${documentData.current_version}`\n : currentVersionId)\n }\n isSnapshot={!!snapshotDocumentId}\n onOpen={(id) => {\n void requestViewerTransition(() => {\n setSnapshotDocumentId(id === currentVersionId ? null : id)\n if (activeTab === 'versions')\n setActiveTab(isArtifact ? 'edit' : isDocx ? 'docx' : 'pdf')\n })\n }}\n onHistory={() => handleTabChange('versions')}\n />\n )}\n </>\n )}\n {!isCompact && titleBlock}\n </ViewerHeaderStart>\n )\n\n const annotatable = canAnnotate({\n activeTab,\n hasPdf: pdfVerified,\n isImage,\n isVideo,\n isAudio,\n isDownloadOnly,\n isDraft,\n isStreaming,\n isSnapshot: !!snapshotDocumentId,\n isComparing,\n })\n const clip = useViewerClipping(annotatable || (!!pdfBlob && (isImage || isVideo)), isCompact)\n const clean = useCleanView(clip.layer, clip.button)\n\n // A request waiting for this user's signature, or their own in flight: shown over the PDF and\n // the Word editor alike; signing happens on the PDF.\n const signatureBanner = !isDraft && !liveKind && !snapshotDocumentId && (\n <SignatureRequestBanner\n documentId={documentId}\n hidden={!!signatureFlow}\n onSign={(request) => {\n void requestViewerTransition(() => {\n setAnnotating(false)\n setPlacingSignature(false)\n if (activeTab !== 'pdf') changeTab('pdf')\n setSignatureFlow({ kind: 'sign', request })\n })\n }}\n onEditDraft={(draft) => {\n void requestViewerTransition(() => {\n if (activeTab !== 'pdf') changeTab('pdf')\n setSignatureFlow({ kind: 'prepare', draft })\n })\n }}\n />\n )\n\n const share = () => {\n const name = (liveKind ? documentTitle : documentData?.file_name) || undefined\n if (support.share) {\n support.share({ id: documentId, name, isPrivate: !documentData?.shared })\n return\n }\n void arbi.documents\n .update([{ external_id: documentId, shared: !documentData?.shared }])\n .then(() => tools.onDocumentsChanged?.([documentId], 'markup'))\n .catch(() => notify(\"Couldn't change who can see this document\", 'error'))\n }\n const shownRef = snapshotDocumentId || documentId\n\n const rightContent = (\n <ViewerHeaderEnd isCompact={isCompact}>\n {/* Annotate: only for a PDF on screen (text and Word files are shown as a PDF too). Marks\n sit in a layer beside the document; Freeze saves a separate copy with them built in. */}\n {annotatable && (\n <AnnotateButton\n active={annotating}\n compact={isCompact}\n onClick={() => {\n setPlacingSignature(false)\n clip.stop()\n markup.setShowOriginal(false)\n setAnnotating((on) => !on)\n }}\n />\n )}\n {clip.button}\n {/* The markup is the default view; \"Show original\" shows the untouched file. */}\n {activeTab === 'pdf' && pdfBlob && !placingSignature && (markup.hasMarkup || annotating) && (\n <ShowOriginalButton\n active={markup.showOriginal}\n compact={isCompact}\n onClick={() => {\n setAnnotating(false)\n markup.setShowOriginal((on) => !on)\n }}\n />\n )}\n {activeTab === 'pdf' && markup.hasMarkup && !annotating && (\n <DownloadMarkupButton\n onClick={() => void markup.downloadMarkup()}\n // A signed version is locked: Download serves the signed file as it is.\n disabledReason={isSigned ? SIGNED_LOCKED_REASON : undefined}\n />\n )}\n {/* Image actions: start a generation from this image, or crop it into a new document. */}\n {activeTab === 'pdf' && isImage && pdfBlob && (\n <ViewerImageActions\n compact={isCompact}\n onUseAsReference={\n support.useImageAsReference ? () => support.useImageAsReference!(documentId) : undefined\n }\n onCrop={crop.handleOpenCrop}\n />\n )}\n {/* The thread it was made in: open it at the answer that made it. */}\n {madeIn && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size={isCompact ? 'icon' : 'sm'}\n onClick={() =>\n openConversation(madeIn.id, {\n messageId: documentData?.source_message_ext_id ?? undefined,\n })\n }\n title={`Open the thread it was made in: ${madeIn.title}`}\n aria-label={`Open the thread it was made in: ${madeIn.title}`}\n data-testid=\"document-open-thread\"\n >\n <MessageSquare className=\"size-4\" />\n {!isCompact && <span className=\"max-w-[10rem] truncate\">{madeIn.title}</span>}\n </Button>\n )}\n {documentId && documentData && !isDraft && !isStreaming && (\n <>\n <FileShareDialog\n open={sharingFile}\n onOpenChange={setSharingFile}\n documentId={documentId}\n version={pdfSnapshotNumber ?? documentData.current_version ?? 1}\n />\n </>\n )}\n {/* Chat about this document: the thread bound to it (its questions edit it), the latest one\n or a new one. Only such a thread drafts in a document: one merely open binds no chat. */}\n {doc.savedDocumentId && !snapshotDocumentId && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size={isCompact ? 'icon' : 'sm'}\n onClick={chatAboutDocument}\n title=\"Chat about this document: a thread that works in it, with edits as tracked changes\"\n aria-label=\"Chat about this document\"\n data-testid=\"document-chat-about\"\n className=\"pointer-coarse:min-h-11\"\n >\n <MessageSquarePlus className=\"size-4\" />\n {!isCompact && <span className=\"ml-1\">Chat</span>}\n </Button>\n )}\n {/* Share always asks first (the host's share dialog), so a click never changes who can see\n the file by surprise. */}\n {documentId && doc.workspaceId && (\n <ShareControl\n state={documentData?.shared ? 'shared' : 'private'}\n onToggle={share}\n disabled={!canChangeVisibility(documentData, currentUserId)}\n disabledTooltip=\"Only the owner can change visibility\"\n tooltip={\n documentData?.shared\n ? 'Shared with the workspace \u2014 click to share with specific people'\n : 'Share with the workspace, then optionally notify specific people by email'\n }\n variant=\"outline\"\n compact={isCompact}\n showState={!isCompact}\n labels={{\n shared: getEntityLabel('WORKSPACE'),\n private: 'Only you',\n mixed: 'Partly shared',\n }}\n testId=\"share-document-button\"\n stateTestId=\"document-title-shared-indicator\"\n />\n )}\n {/* Finalise (a translation): its current version saved as a new labelled PDF. */}\n {!isStreaming && !snapshotDocumentId && (\n <FinaliseTranslationButton document={documentData ?? undefined} isCompact={isCompact} />\n )}\n {/* Every signing action starts in one menu: sign yourself, save/place a mark, or request\n signatures from others. */}\n {annotatable && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant={\n placingSignature || signatureFlow?.kind === 'prepare' ? 'default' : 'outline'\n }\n size={isCompact ? 'icon' : 'sm'}\n aria-label=\"Sign\"\n title=\"Sign or request signatures\"\n data-testid=\"signing-menu-trigger\"\n className=\"pointer-coarse:min-h-11\"\n >\n <Signature className=\"size-4\" />\n {!isCompact && <span className=\"ml-1\">Sign</span>}\n <ChevronDown className=\"ml-1 size-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" forceMount>\n <DropdownMenuItem\n data-testid=\"sign-document-button\"\n onSelect={() => {\n setAnnotating(false)\n if (isSigned) {\n setSignatureFlow(null)\n setPlacingSignature((on) => !on)\n } else {\n setPlacingSignature(false)\n setSignatureFlow({ kind: 'prepare', self: true })\n }\n }}\n >\n <PenLine className=\"mr-2 size-4\" /> Sign this document\n </DropdownMenuItem>\n {!isSigned && (\n <>\n <PlaceMySignatureMenuItems\n onPlace={(mark) => {\n setPlacingSignature(false)\n setSignatureFlow(null)\n markup.setShowOriginal(false)\n setAnnotating(true)\n setPlaceMark({ ...mark, key: Date.now() })\n }}\n />\n <DropdownMenuItem\n data-testid=\"request-signatures-button\"\n onSelect={() => {\n setAnnotating(false)\n setPlacingSignature(false)\n setSignatureFlow(signatureFlow?.kind === 'prepare' ? null : { kind: 'prepare' })\n }}\n >\n <Users className=\"mr-2 size-4\" /> Ask someone to sign\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {isSignOpen && pdfBlob && pdfVerified && signingScopeMatches && (\n <SignDocumentDialog\n open={isSignOpen}\n onOpenChange={setIsSignOpen}\n documentId={documentId}\n pdfBlob={pdfBlob}\n // The PDF on screen is the current version's (an earlier one cannot be signed): the\n // server refuses if another version has landed since.\n version={documentData?.current_version ?? undefined}\n appearance={signAppearance}\n />\n )}\n <ViewerMoreMenu\n compact={isCompact}\n items={[\n ...(documentId && documentData && !isDraft && !isStreaming\n ? [\n {\n key: 'share-file',\n label: 'Share file\u2026',\n icon: <Link2 className=\"size-4\" />,\n description: 'Send a link to this version of the file',\n onSelect: () => setSharingFile(true),\n testId: 'share-file-button',\n },\n ]\n : []),\n ...(tools.emailDocument && !isDraft && !isStreaming && documentData?.file_name\n ? [\n {\n key: 'email',\n label: 'Email\u2026',\n icon: <Mail className=\"size-4\" />,\n description: 'Email this document (attached)',\n onSelect: () => tools.emailDocument?.(shownRef),\n testId: 'email-document-button',\n },\n ]\n : []),\n ...(support.translate &&\n !isDraft &&\n !isStreaming &&\n !liveKind &&\n !isImage &&\n documentData?.file_name\n ? [\n {\n key: 'translate',\n label: 'Translate\u2026',\n icon: <Languages className=\"size-4\" />,\n description: 'A new editable document, original and translation side by side',\n onSelect: () => support.translate!(shownRef),\n testId: 'translate-document-button',\n },\n ]\n : []),\n ]}\n />\n {headerActions}\n </ViewerHeaderEnd>\n )\n\n const viewerProps = {\n currentPage: viewingDocumentPage || undefined,\n onLoadSuccess: handleLoadSuccess,\n scrollTrigger,\n zoom,\n onZoomChange: setZoom,\n }\n\n return (\n <ViewerFrame\n frameRef={containerRef}\n contentId={documentId}\n header={\n <>\n <TabHeader\n tabs={[]}\n activeTabId={activeTab}\n onTabChange={handleTabChange}\n leftContent={leftContent}\n rightContent={rightContent}\n variant=\"underline\"\n />\n {isCompact && !isCoEditing && (\n <div data-slot=\"viewer-title-row\" className=\"flex min-w-0 items-center gap-2 px-3 pb-2\">\n {titleBlock}\n </div>\n )}\n {/* In the sticky header, not the content area: the PDF view scrolls its first page into\n view, which scrolls a bar above it out of sight. */}\n {snapshotDocumentId && (\n <VersionSnapshotBar\n versionNumber={snapshotNumber}\n live={isDocx || isArtifact}\n onAsk={\n support.askAboutVersion\n ? () => support.askAboutVersion!(snapshotDocumentId)\n : undefined\n }\n onReturn={() => setSnapshotDocumentId(null)}\n />\n )}\n </>\n }\n compareRow={isComparing ? compareIndicator || undefined : undefined}\n {...clean.frame}\n footer={<ViewerCropModal crop={crop} />}\n >\n {isComparing && (\n <Suspense fallback={<ViewerMessage>Loading comparison\u2026</ViewerMessage>}>\n <NativeDocxComparison\n baseId={compareDocumentId!}\n revisedId={documentId}\n title={documentTitle}\n />\n </Suspense>\n )}\n {/* A capture draft (photo/video/audio) has no backend document at all until it is saved:\n its recorder takes over the whole content area. */}\n {isCaptureDraft && <ViewerCaptureDraft documentId={documentId} />}\n\n {/* Media stay mounted (hidden) on the text tab, so playback goes on while reading the\n transcript. */}\n {!isCaptureDraft &&\n (activeTab === 'pdf' || (isMedia && activeTab === 'html')) &&\n (!isArtifact || (isDocx && !isDraft && !isStreaming && !liveKind)) &&\n !isComparing && (\n <ViewerPane hidden={activeTab !== 'pdf'}>\n {/* The labels are the document's, whichever view it is read in: the PDF gets the\n chips without the passage stepper (no parsed passages to walk here). */}\n {!clean.on && <DocumentLabelBar summaries={labelSummaries} />}\n {!clean.on && !isMedia && !isImage && signatureBanner}\n {!clean.on && activeTab === 'pdf' && pdfBlob && !pdfVerified && (\n <ViewerMessage>\n Offline copy: its version cannot be verified. Reconnect before signing.{' '}\n <button type=\"button\" onClick={() => void blobs.retryPdf()} className=\"underline\">\n Retry loading the current PDF\n </button>\n </ViewerMessage>\n )}\n {!clean.on && activeTab === 'pdf' && !isMedia && !isImage && (\n <MarkupNotices\n legacyPrompt={markup.legacyPrompt}\n olderNote={markup.olderNote}\n onOpenVersion={(n) => setSnapshotDocumentId(`${documentId}@v${n}`)}\n />\n )}\n <ViewerControlBar controls={!clean.on && activeTab === 'pdf' && pageNav}>\n <ViewerPdfPane\n documentId={documentId}\n doc={doc}\n pdfBlob={pdfBlob}\n isPdfLoading={!versionReady || blobs.isPdfLoading}\n pdfError={blobs.pdfError}\n onDownload={() => void handleDirectDownload()}\n viewerProps={viewerProps}\n signatureFlow={pdfVerified && signingScopeMatches ? signatureFlow : null}\n onSignatureFlow={setSignatureFlow}\n currentUserId={currentUserId}\n placingSignature={pdfVerified && signingScopeMatches && placingSignature}\n onPlacingDone={(appearance) => {\n setPlacingSignature(false)\n if (!appearance) return\n setSignAppearance(appearance)\n setIsSignOpen(true)\n }}\n annotating={annotating}\n clipping={clip.clipping}\n markup={markup}\n pdfSnapshotNumber={pdfSnapshotNumber}\n isSigned={isSigned}\n placeMark={placeMark}\n />\n </ViewerControlBar>\n </ViewerPane>\n )}\n\n {activeTab === 'preview' && isArtifact && liveKind && (\n // The preview loads its JSX compiler on first use, so it stays out of the main bundle.\n <ArtifactPreview\n kind={liveKind}\n source={liveSource}\n isStreaming={isStreaming}\n runtimeUrl={artifactRuntimeUrl}\n />\n )}\n\n {activeTab === 'edit' && isArtifact && liveKind && (\n <ArtifactCodeView source={liveSource} fileName={documentData?.file_name ?? undefined} />\n )}\n\n {/* A document draft is stored as DOCX: once generation ends the Word editor opens the stored\n document. Only a draft still being generated shows the streamed preview. */}\n {activeTab === 'edit' && isArtifact && !liveKind && !isStreaming && !isComparing && (\n <Suspense fallback={<ViewerMessage>Loading editor\u2026</ViewerMessage>}>\n {isSigned && !snapshotDocumentId && <SignedEditNote />}\n <NativeDocxEditor\n key={`${snapshotDocumentId || documentId}-${snapshotDocumentId ? 'snapshot' : 'live'}`}\n documentId={snapshotDocumentId || documentId}\n title={documentTitle}\n draftContent={isDraft ? draftDoc?.content || '' : undefined}\n snapshot={!!snapshotDocumentId}\n saveRef={saveWordRef}\n onSaved={(id) => {\n if (!isDraft) return\n session.clearDraftDocument(documentId)\n setViewingDocumentId(id)\n }}\n />\n </Suspense>\n )}\n\n {activeTab === 'versions' && (isArtifact || isDocx || hasHistory) && !isComparing && (\n <VersionTimeline\n // Each version made in a thread names it and opens it at the turn that made it.\n versions={versions.map((v) => ({\n ...v,\n madeIn: v.thread\n ? {\n label: threadTitle(v.thread.conversationId),\n onOpen: () =>\n openConversation(v.thread!.conversationId, {\n messageId: v.thread!.messageId ?? undefined,\n }),\n }\n : null,\n }))}\n currentId={currentVersionId}\n live={!!liveKind}\n // An uploaded file is not a draft: its versions come from replacing, editing or signing.\n labels={isArtifact ? undefined : { emptyDocument: UPLOADED_NO_VERSIONS }}\n formatDate={formatDate}\n onOpen={(id) => {\n // The current version is the live document itself, not a read-only copy of it.\n setSnapshotDocumentId(id === currentVersionId ? null : id)\n setActiveTab(isArtifact ? 'edit' : isDocx ? 'docx' : 'pdf')\n }}\n onCompare={(id) => session.setDocumentViewer({ compareId: id, tab: 'html' })}\n translations={translations}\n onOpenTranslation={(id) => setViewingDocumentId(id)}\n />\n )}\n\n {activeTab === 'xlsx' &&\n isXlsx &&\n (xlsxBlob ? (\n <XlsxViewer blob={xlsxBlob} />\n ) : (\n <ViewerMessage>\n {xlsxError ? 'Failed to load spreadsheet' : 'Loading spreadsheet...'}\n </ViewerMessage>\n ))}\n\n {activeTab === 'slides' && isPresentation && (\n <Suspense fallback={<ViewerMessage>Loading slides\u2026</ViewerMessage>}>\n <SlidesTab\n documentId={documentId}\n version={snapshotDocumentId ? snapshotNumber : undefined}\n currentVersion={documentData?.current_version ?? undefined}\n draftTitle={isDraft ? (draftDoc?.title ?? '') : undefined}\n />\n </Suspense>\n )}\n {activeTab === 'docx' && isDocx && !isComparing && (\n <Suspense fallback={<ViewerMessage>Loading editor\u2026</ViewerMessage>}>\n {signatureBanner}\n {isSigned && !snapshotDocumentId && <SignedEditNote />}\n <NativeDocxEditor\n key={`${snapshotDocumentId || documentId}-${snapshotDocumentId ? 'snapshot' : 'live'}`}\n documentId={snapshotDocumentId || documentId}\n title={documentTitle}\n snapshot={!!snapshotDocumentId}\n saveRef={saveWordRef}\n />\n </Suspense>\n )}\n\n {streamingDoc &&\n isStreaming &&\n isArtifact &&\n !liveKind &&\n !isComparing &&\n (activeTab === 'html' || activeTab === 'edit') && (\n <Suspense fallback={<ViewerMessage>Opening draft\u2026</ViewerMessage>}>\n <StreamedWordArtifact\n key={documentId}\n documentId={documentId.startsWith('doc-') ? documentId : undefined}\n title={documentTitle}\n content={streamingDoc.content}\n busy={isStreaming}\n />\n </Suspense>\n )}\n\n {!isCaptureDraft &&\n !isComparing &&\n activeTab === 'html' &&\n !(isStreaming && isArtifact && !liveKind) && (\n <ViewerPane>\n <ViewerControlBar controls={pageNav}>\n <ParsedTextView\n documentId={pdfSnapshotId || documentId}\n onLoadSuccess={handleLoadSuccess}\n scrollTrigger={scrollTrigger}\n zoom={zoom}\n onZoomChange={setZoom}\n />\n </ViewerControlBar>\n </ViewerPane>\n )}\n </ViewerFrame>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,7 +3,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useRef } from "react";
|
|
4
4
|
import { useArbiSessionState, useArbiSessionStore } from "@arbidocs/react";
|
|
5
5
|
import { CleanViewControl } from "./CleanViewControl.js";
|
|
6
|
-
function useCleanView(extra) {
|
|
6
|
+
function useCleanView(extra, controls) {
|
|
7
7
|
const session = useArbiSessionStore();
|
|
8
8
|
const detached = useArbiSessionState((s) => s.documentViewer.detached);
|
|
9
9
|
const presenting = useArbiSessionState((s) => s.documentViewer.presenting);
|
|
@@ -20,7 +20,7 @@ function useCleanView(extra) {
|
|
|
20
20
|
frame: {
|
|
21
21
|
bare: on,
|
|
22
22
|
overlay: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
23
|
-
on && /* @__PURE__ */ jsx(CleanViewControl, { onExit: () => session.setDocumentViewer({ presenting: false }) }),
|
|
23
|
+
on && /* @__PURE__ */ jsx(CleanViewControl, { onExit: () => session.setDocumentViewer({ presenting: false }), children: controls }),
|
|
24
24
|
extra
|
|
25
25
|
] })
|
|
26
26
|
}
|