collabmd 0.1.44 → 0.1.46
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 +39 -19
- package/bin/collabmd.js +27 -1
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-CYM5nxUi.js +1 -0
- package/dist/client/assets/browser-utils--H_DkyEF.js +1 -0
- package/dist/client/assets/chunk-ERSWUTIN-hHdvnhaY.js +41 -0
- package/dist/client/assets/{chunk-CZQZEIFA-DT3N9fo7.js → chunk-YGJVY4SA-CjSe7Bx7.js} +2 -2
- package/dist/client/assets/comment-thread-store-CdcwrObc.js +1 -0
- package/dist/client/assets/comment-threads-9J6Em-_y.js +4 -0
- package/dist/client/assets/comment-ui-shared-BC4pt4w8.js +7 -0
- package/dist/client/assets/dist-B5HTH2BO.js +1 -0
- package/dist/client/assets/{dist-DhLvC8DS.js → dist-B5Jf1SLZ.js} +2 -2
- package/dist/client/assets/{dist-CnL7Y2sM.js → dist-BDt3rz7l.js} +1 -1
- package/dist/client/assets/dist-BEwK4csK.js +1 -0
- package/dist/client/assets/dist-BKW4PALF.js +1 -0
- package/dist/client/assets/dist-BWcHHOx-.js +1 -0
- package/dist/client/assets/{dist-CYZmbokb.js → dist-BalScOwZ.js} +9 -9
- package/dist/client/assets/dist-Bf8f4HmM.js +6 -0
- package/dist/client/assets/dist-BjHJDtyU.js +1 -0
- package/dist/client/assets/dist-Bm6pf9Bl.js +1 -0
- package/dist/client/assets/dist-BoVBdSjk.js +1 -0
- package/dist/client/assets/dist-CC5IrQMG.js +1 -0
- package/dist/client/assets/{dist-C11hHqv_.js → dist-CCP_AKPG.js} +12 -12
- package/dist/client/assets/dist-CZgOmxK6.js +1 -0
- package/dist/client/assets/{dist-D2AQ-76g.js → dist-Cqhv5LAk.js} +1 -1
- package/dist/client/assets/{dist-MvcV4190.js → dist-D-Z6FLem.js} +1 -1
- package/dist/client/assets/dist-DLMiIsNC.js +11 -0
- package/dist/client/assets/{dist-3bgCp7iY.js → dist-DZKu9Cs8.js} +1 -1
- package/dist/client/assets/dist-DaYdhcVs.js +1 -0
- package/dist/client/assets/dist-FWJsgGYI.js +1 -0
- package/dist/client/assets/dist-Kh2COra_.js +1 -0
- package/dist/client/assets/{dist-JYEDRrPT.js → dist-PDZ3bSqm.js} +1 -1
- package/dist/client/assets/{dist-Drp8uu5J.js → dist-TjMh8n1u.js} +1 -1
- package/dist/client/assets/{dist-DGb27Dl6.js → dist-dtAdgL39.js} +1 -1
- package/dist/client/assets/dist-jv4WdPnK.js +9 -0
- package/dist/client/assets/{dist-DK5Gs2wa.js → dist-rGBmqxC7.js} +1 -1
- package/dist/client/assets/{dist-DCzuX1AF.js → dist-shrl6K_0.js} +1 -1
- package/dist/client/assets/dist-tOaegDYS2.js +1 -0
- package/dist/client/assets/dist-ule2n6ak.js +1 -0
- package/dist/client/assets/dist-xElaxbia.js +1 -0
- package/dist/client/assets/drawio-editor-FzY1cVw8.js +9 -0
- package/dist/client/assets/drawioEditor-BjiKJqlc.js +2 -0
- package/dist/client/assets/editor-session-Cm9ekeNo.js +54 -0
- package/dist/client/assets/embedded-editor-base-CwTkk911.css +1 -0
- package/dist/client/assets/{en-GADW4C6J-DQ6zyCEM.js → en-7NFCYGKX-BrgYZAEe.js} +1 -1
- package/dist/client/assets/{preview-render-profile-BZzGSg6K.js → es-DXGV3RHd.js} +13 -13
- package/dist/client/assets/excalidraw-editor-B46zsTFI.js +9 -0
- package/dist/client/assets/excalidraw-editor-Bt7gMSoh.css +1 -0
- package/dist/client/assets/excalidraw-scene-BOben2gr.js +1 -0
- package/dist/client/assets/excalidrawEditor-CT2pHq7e.js +2 -0
- package/dist/client/assets/export-page-A7NHawJY.js +39 -0
- package/dist/client/assets/exportDocument-B2L8fe34.css +1 -0
- package/dist/client/assets/exportDocument-BaqcOAAW.js +2 -0
- package/dist/client/assets/file-icon-svg-CQAjlWjK.js +1 -0
- package/dist/client/assets/file-kind-BbqgGzpc.js +1 -0
- package/dist/client/assets/image-QXRYHUNP-SWEV8H0J.js +1 -0
- package/dist/client/assets/index-ClbjMBVt.js +2 -0
- package/dist/client/assets/index-Pum8ET-5.css +1 -0
- package/dist/client/assets/main-B3uPyqic.js +893 -0
- package/dist/client/assets/modulepreload-polyfill-P2Xu9kJm.js +1 -0
- package/dist/client/assets/pdf-BL9Pr2D5.js +54 -0
- package/dist/client/assets/pdf.worker-CLesOks4.mjs +64857 -0
- package/dist/client/assets/pdf_viewer-FVkkThnz.js +551 -0
- package/dist/client/assets/preview-diagram-utils-txBCoW8d.js +1 -0
- package/dist/client/assets/{preview-render-compiler-BSaQO_p3.js → preview-render-compiler-BD-XhkS2.js} +2 -2
- package/dist/client/assets/preview-render-compiler-BKedaMxx.js +1 -0
- package/dist/client/assets/preview-render-profile-CE-5rVTC.js +1 -0
- package/dist/client/assets/{preview-render-worker-B42LWvrD.js → preview-render-worker-CiPqc9n6.js} +20 -20
- package/dist/client/assets/prod-Dy20X7eT.js +1 -0
- package/dist/client/assets/prod-hnwh7wRM.js +177 -0
- package/dist/client/assets/quick-switcher-controller-fqOYR7qR.js +12 -0
- package/dist/client/assets/runtime-config-BLrEKVO1.js +1 -0
- package/dist/client/assets/vault-api-client-_LpV1aIn.js +6 -0
- package/dist/client/assets/{yjs-provider-reset-guard-Cox4nxwu.js → yjs-provider-reset-guard-DE0vINDP.js} +1 -1
- package/dist/client/drawio-editor.html +3 -2
- package/dist/client/excalidraw-editor.html +3 -2
- package/dist/client/export-document.html +4 -3
- package/dist/client/index.html +109 -27
- package/docker-compose.yml +42 -0
- package/package.json +26 -15
- package/scripts/local-structurizr-compose.mjs +101 -0
- package/src/client/app/drawio-editor-entry.js +0 -3
- package/src/client/app/drawio-editor.html +1 -0
- package/src/client/app/excalidraw-editor-entry.js +0 -3
- package/src/client/app/excalidraw-editor.html +1 -0
- package/src/client/app/export-document-entry.js +0 -3
- package/src/client/app/export-document.html +1 -0
- package/src/client/app/index.html +106 -24
- package/src/client/app/main-entry.js +0 -5
- package/src/client/application/app-shell/chat-feature.js +180 -124
- package/src/client/application/app-shell/comments-feature.js +20 -11
- package/src/client/application/app-shell/git-feature.js +16 -9
- package/src/client/application/app-shell/presence-feature.js +18 -11
- package/src/client/application/app-shell/ui-feature-shell.js +78 -17
- package/src/client/application/app-shell/ui-feature-sidebar.js +74 -1
- package/src/client/application/app-shell/ui-feature-tab-activity.js +2 -2
- package/src/client/application/app-shell/ui-feature-toolbar.js +2 -52
- package/src/client/application/app-shell/workspace-feature.js +27 -84
- package/src/client/application/app-shell-elements.js +9 -1
- package/src/client/application/diagram-chrome.js +161 -166
- package/src/client/application/diagram-preview-export.js +7 -34
- package/src/client/application/diagram-preview-hydrator.js +1 -19
- package/src/client/application/markdown-frontmatter.js +0 -2
- package/src/client/application/mermaid-preview-hydrator.js +1 -14
- package/src/client/application/pdf-preview-controller.js +992 -0
- package/src/client/application/plantuml-preview-hydrator.js +0 -10
- package/src/client/application/preview-diagram-utils.js +31 -2
- package/src/client/application/preview-render-compiler.js +2 -1
- package/src/client/application/preview-renderer.js +2 -2
- package/src/client/application/quick-switcher-loader.js +3 -1
- package/src/client/application/structurizr-preview-controller.js +395 -0
- package/src/client/application/workspace-coordinator.js +25 -3
- package/src/client/application/workspace-preview-controller.js +91 -5
- package/src/client/bootstrap/collabmd-app-shell.js +155 -43
- package/src/client/browser-utils.js +44 -0
- package/src/client/domain/excalidraw-collaboration.js +0 -2
- package/src/client/domain/room.js +38 -0
- package/src/client/domain/runtime-paths.js +26 -5
- package/src/client/domain/structurizr-language.js +99 -0
- package/src/client/domain/vault-paths.js +48 -0
- package/src/client/excalidraw-editor.js +833 -51
- package/src/client/export/export-pipeline.js +6 -34
- package/src/client/infrastructure/auth-client.js +4 -10
- package/src/client/infrastructure/browser-notification-port.js +33 -20
- package/src/client/infrastructure/browser-preferences-port.js +46 -9
- package/src/client/infrastructure/comment-thread-store.js +34 -13
- package/src/client/infrastructure/editor-session.js +10 -0
- package/src/client/infrastructure/editor-view-adapter.js +133 -5
- package/src/client/infrastructure/excalidraw-room-client.js +103 -14
- package/src/client/infrastructure/git-api-client.js +5 -0
- package/src/client/infrastructure/lobby-presence.js +1 -0
- package/src/client/infrastructure/vault-api-client.js +51 -0
- package/src/client/infrastructure/workspace-sync-client.js +13 -1
- package/src/client/presentation/comment-overview-controller.js +18 -53
- package/src/client/presentation/comment-ui/comment-ui-card.js +1 -12
- package/src/client/presentation/comment-ui/comment-ui-layout.js +242 -219
- package/src/client/presentation/comment-ui/comment-ui-render.js +32 -45
- package/src/client/presentation/comment-ui/comment-ui-shared.js +68 -13
- package/src/client/presentation/comment-ui-controller.js +5 -1
- package/src/client/presentation/drawio-embed-controller.js +9 -102
- package/src/client/presentation/drawio-viewer.js +118 -0
- package/src/client/presentation/excalidraw-embed-controller.js +74 -8
- package/src/client/presentation/file-action-controller.js +134 -0
- package/src/client/presentation/file-explorer-controller.js +33 -3
- package/src/client/presentation/file-explorer-view.js +59 -34
- package/src/client/presentation/file-icon-svg.js +40 -0
- package/src/client/presentation/file-tree-state.js +12 -4
- package/src/client/presentation/git-diff-view-controller.js +731 -3
- package/src/client/presentation/outline-controller.js +86 -0
- package/src/client/presentation/quick-switcher-controller.js +257 -74
- package/src/client/presentation/quick-switcher-text-search.js +3 -3
- package/src/client/presentation/toast-controller.js +3 -0
- package/src/client/styles/components/feedback.css +6 -0
- package/src/client/styles/components/navigation.css +11 -1
- package/src/client/styles/features/collaboration-chat.css +49 -53
- package/src/client/styles/features/collaboration-presence.css +9 -7
- package/src/client/styles/features/comment-card.css +25 -11
- package/src/client/styles/features/comment-overlays.css +0 -4
- package/src/client/styles/features/comment-overview.css +44 -21
- package/src/client/styles/features/comments-drawer.css +2 -100
- package/src/client/styles/features/diagram-preview.css +81 -18
- package/src/client/styles/features/diff-special.css +309 -0
- package/src/client/styles/features/embedded-preview.css +8 -33
- package/src/client/styles/features/quick-switcher.css +8 -0
- package/src/client/styles/foundation/themes.css +6 -0
- package/src/client/styles/foundation/tokens.css +1 -0
- package/src/client/styles/layout/editor-page.css +40 -0
- package/src/client/styles/layout/responsive.css +31 -1
- package/src/client/styles/layout/shell.css +383 -7
- package/src/client/styles/layout/sidebar.css +47 -15
- package/src/client/styles/layout/view-modes.css +1 -0
- package/src/client/styles/overrides/codemirror.css +217 -15
- package/src/client/styles/style.css +1 -0
- package/src/client/styles/surfaces/excalidraw-editor.css +294 -0
- package/src/domain/comment-threads.js +63 -5
- package/src/domain/excalidraw-room-codec.js +6 -4
- package/src/domain/file-kind.js +35 -3
- package/src/server/application/workspace-reconciliation.js +1 -1
- package/src/server/config/env.js +79 -0
- package/src/server/create-app-server.js +14 -3
- package/src/server/domain/bases/base-definition.js +1 -1
- package/src/server/domain/bases/base-expression-runtime.js +1 -4
- package/src/server/domain/bases/base-index-snapshot-store.js +1 -4
- package/src/server/domain/bases/base-query-service.js +1 -77
- package/src/server/domain/bases/base-transform.js +1 -4
- package/src/server/domain/collaboration/collaboration-room.js +55 -21
- package/src/server/domain/comment-overview.js +25 -8
- package/src/server/domain/docx-exporter.js +24 -33
- package/src/server/domain/ripgrep-search-service.js +7 -1
- package/src/server/domain/workspace-state.js +32 -11
- package/src/server/infrastructure/git/diff-service.js +29 -13
- package/src/server/infrastructure/git/git-service.js +61 -10
- package/src/server/infrastructure/git/history-service.js +96 -29
- package/src/server/infrastructure/git/image-mime.js +14 -0
- package/src/server/infrastructure/git/path-utils.js +1 -1
- package/src/server/infrastructure/git/responses.js +0 -95
- package/src/server/infrastructure/git/untracked-files.js +28 -1
- package/src/server/infrastructure/github/github-app-client.js +22 -15
- package/src/server/infrastructure/http/create-git-api-query-handler.js +31 -1
- package/src/server/infrastructure/http/create-request-handler.js +18 -31
- package/src/server/infrastructure/http/create-static-handler.js +5 -2
- package/src/server/infrastructure/http/create-structurizr-api-handler.js +145 -0
- package/src/server/infrastructure/http/create-vault-api-command-handler.js +70 -8
- package/src/server/infrastructure/http/create-vault-api-query-handler.js +51 -3
- package/src/server/infrastructure/http/http-errors.js +7 -1
- package/src/server/infrastructure/http/http-request-helpers.js +22 -0
- package/src/server/infrastructure/persistence/path-utils.js +1 -1
- package/src/server/infrastructure/persistence/vault-file-store.js +3 -0
- package/src/server/infrastructure/structurizr/structurizr-embed.css +43 -0
- package/src/server/infrastructure/structurizr/structurizr-workspace-service.js +374 -0
- package/src/server/infrastructure/websocket/attach-collaboration-gateway.js +4 -22
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-CbSISC1w.js +0 -1
- package/dist/client/assets/bases-preview-controller-2pLHk0uk.js +0 -143
- package/dist/client/assets/browser-utils-CKtI_rZl.js +0 -1
- package/dist/client/assets/button-BCEiw4Rw.js +0 -1
- package/dist/client/assets/chunk-AXR3VHVW-0GTk_evH.js +0 -41
- package/dist/client/assets/comment-threads-D-iKphIp.js +0 -4
- package/dist/client/assets/diagram-action-icons-aa_KOv9h.js +0 -36
- package/dist/client/assets/dist-BH87JoHx.js +0 -11
- package/dist/client/assets/dist-BIkPRZO7.js +0 -6
- package/dist/client/assets/dist-BqCsFpx4.js +0 -1
- package/dist/client/assets/dist-C2JHCt8U.js +0 -1
- package/dist/client/assets/dist-CZjTtmTu.js +0 -1
- package/dist/client/assets/dist-Cig4Ov_X.js +0 -1
- package/dist/client/assets/dist-CqQEC8gR.js +0 -1
- package/dist/client/assets/dist-D4Rzqod1.js +0 -1
- package/dist/client/assets/dist-D5sn-mwk.js +0 -9
- package/dist/client/assets/dist-D7G-n87v.js +0 -1
- package/dist/client/assets/dist-DRqOrNgN.js +0 -1
- package/dist/client/assets/dist-DetkMS_4.js +0 -1
- package/dist/client/assets/dist-Dp6FVkQ1.js +0 -1
- package/dist/client/assets/dist-DtbjNB28.js +0 -1
- package/dist/client/assets/dist-DyrYcvpo2.js +0 -1
- package/dist/client/assets/dist-GrygD2zE.js +0 -1
- package/dist/client/assets/dist-HmEpWUow.js +0 -1
- package/dist/client/assets/dist-RTa81Km7.js +0 -1
- package/dist/client/assets/drawio-editor-DDvFoarP.js +0 -9
- package/dist/client/assets/drawio-embed-controller-BD1GTRwn.js +0 -1
- package/dist/client/assets/drawioEditor-Bu5grlH5.js +0 -2
- package/dist/client/assets/editor-session-DGlpiAsK.js +0 -16
- package/dist/client/assets/embedded-editor-base-C9roKYpW.css +0 -1
- package/dist/client/assets/excalidraw-editor-BHu6k8d4.js +0 -9
- package/dist/client/assets/excalidraw-editor-Cr_184EF.css +0 -1
- package/dist/client/assets/excalidraw-embed-controller-y2fenN_g.js +0 -1
- package/dist/client/assets/excalidraw-embed-reconciler-DGiagExg.js +0 -1
- package/dist/client/assets/excalidraw-scene-BvsQ6mLP.js +0 -176
- package/dist/client/assets/excalidrawEditor-4vFE--Uw.js +0 -2
- package/dist/client/assets/export-page-Cby8JzPO.js +0 -39
- package/dist/client/assets/exportDocument-C9v-bc7I.css +0 -1
- package/dist/client/assets/exportDocument-CRHCfsdo.js +0 -2
- package/dist/client/assets/file-history-view-controller-BDjEV9xJ.js +0 -112
- package/dist/client/assets/file-kind-BKPOIRPE.js +0 -1
- package/dist/client/assets/git-diff-view-controller-DgdM1aqb.js +0 -150
- package/dist/client/assets/git-panel-controller-BDTR2HVp.js +0 -207
- package/dist/client/assets/image-XGD7JQR6-XDUWHRpO.js +0 -1
- package/dist/client/assets/index-7xOyXDhP.css +0 -1
- package/dist/client/assets/index-Bz1KuQ6y.js +0 -2
- package/dist/client/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/client/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/client/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/client/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/client/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/client/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/client/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- package/dist/client/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- package/dist/client/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/dist/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- package/dist/client/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- package/dist/client/assets/main-Ci07m9oP.js +0 -152
- package/dist/client/assets/preview-diagram-utils-n_bbJA9V.js +0 -1
- package/dist/client/assets/preview-render-compiler-csGM5ZFz.js +0 -1
- package/dist/client/assets/quick-switcher-controller-CoiYvllm.js +0 -12
- package/dist/client/assets/room-CDrmIdDt.js +0 -1
- package/dist/client/assets/runtime-config-CDgeuPWN.js +0 -1
- package/dist/client/assets/runtime-config-loader-BHGniHP5.js +0 -1
- package/dist/client/assets/runtime-paths-DvpihCEq.js +0 -1
- package/dist/client/assets/segmented-control-DJrHSz8M.js +0 -1
- package/dist/client/assets/vault-api-client-sLB2bo56.js +0 -1
- package/dist/client/assets/vault-paths-CVkuh0j-.js +0 -5
- package/src/client/bootstrap/lazy-controller-feature.js +0 -433
- package/src/client/infrastructure/backlinks-api-client.js +0 -16
- package/src/client/infrastructure/plantuml-api-client.js +0 -19
- package/src/client/infrastructure/runtime-config-loader.js +0 -56
- package/src/server/domain/collaboration/room-persistence-controller.js +0 -80
- package/src/server/infrastructure/git/command-runner.js +0 -49
- package/src/server/infrastructure/git/errors.js +0 -8
- package/src/server/infrastructure/http/create-esm-proxy-handler.js +0 -130
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getVaultFileKind,
|
|
3
|
+
supportsCommentsForFilePath,
|
|
4
|
+
} from '../../../domain/file-kind.js';
|
|
2
5
|
|
|
3
6
|
export const commentsFeature = {
|
|
4
7
|
createCommentThread(payload) {
|
|
@@ -82,26 +85,32 @@ export const commentsFeature = {
|
|
|
82
85
|
return;
|
|
83
86
|
}
|
|
84
87
|
|
|
88
|
+
const isDiagram = getVaultFileKind(filePath) === 'excalidraw';
|
|
85
89
|
const line = Number.isFinite(anchor?.startLine) ? anchor.startLine : null;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
if (!isDiagram) {
|
|
91
|
+
this._pendingCommentOverviewFocus = {
|
|
92
|
+
attempts: 0,
|
|
93
|
+
filePath,
|
|
94
|
+
line,
|
|
95
|
+
threadId,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
92
98
|
this.setSidebarTab('comments');
|
|
93
99
|
this.setSidebarVisibility(true);
|
|
94
100
|
this.workspaceRouteController?.preserveSidebarTabForNextFileRoute?.(filePath);
|
|
95
|
-
this.navigation.navigateToFile(filePath, {
|
|
96
|
-
line,
|
|
97
|
-
});
|
|
101
|
+
this.navigation.navigateToFile(filePath, isDiagram ? undefined : { line });
|
|
98
102
|
|
|
99
103
|
if (this.currentFilePath !== filePath || !this.session) {
|
|
100
|
-
await this.openFile(filePath);
|
|
104
|
+
await this.workspaceRouteController.openFile(filePath);
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
this.setSidebarTab('comments');
|
|
104
108
|
this.setSidebarVisibility(true);
|
|
109
|
+
if (isDiagram) {
|
|
110
|
+
this.excalidrawEmbed?.openCommentThread?.(filePath, threadId);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
105
114
|
this.focusPendingCommentOverviewThread();
|
|
106
115
|
},
|
|
107
116
|
|
|
@@ -148,7 +148,7 @@ export const gitFeature = {
|
|
|
148
148
|
|
|
149
149
|
syncMainChrome({ badgeLabel = '', mode, title = null } = {}) {
|
|
150
150
|
const isSpecialMode = mode === 'diff' || mode === 'history' || mode === 'history-preview';
|
|
151
|
-
this.elements.
|
|
151
|
+
this.elements.toolbarViewToggle?.classList.toggle('hidden', isSpecialMode);
|
|
152
152
|
this.elements.mobileViewToggle?.classList.toggle('hidden', isSpecialMode);
|
|
153
153
|
this.elements.userCount?.classList.toggle('hidden', isSpecialMode);
|
|
154
154
|
this.elements.toolbarDiffBadge?.classList.toggle('hidden', !badgeLabel);
|
|
@@ -164,7 +164,6 @@ export const gitFeature = {
|
|
|
164
164
|
},
|
|
165
165
|
|
|
166
166
|
async showGitDiff({ filePath = null, scope = 'all' } = {}) {
|
|
167
|
-
await this.ensureGitControllers?.();
|
|
168
167
|
this.clearStaticPreviewDocument?.();
|
|
169
168
|
this.gitPanel.setSelection(filePath ? { path: filePath, scope, source: 'workspace' } : {});
|
|
170
169
|
this.gitPanel.setMode('changes');
|
|
@@ -179,7 +178,6 @@ export const gitFeature = {
|
|
|
179
178
|
},
|
|
180
179
|
|
|
181
180
|
async showGitCommit({ hash, path = null, historyFilePath = null } = {}) {
|
|
182
|
-
await this.ensureGitControllers?.();
|
|
183
181
|
this.clearStaticPreviewDocument?.();
|
|
184
182
|
this.gitPanel.setMode('history');
|
|
185
183
|
this.gitPanel.setSelection(hash ? { commitHash: hash, path, source: 'commit' } : { source: 'commit' });
|
|
@@ -194,7 +192,6 @@ export const gitFeature = {
|
|
|
194
192
|
},
|
|
195
193
|
|
|
196
194
|
async showGitHistory() {
|
|
197
|
-
await this.ensureGitControllers?.();
|
|
198
195
|
this.clearStaticPreviewDocument?.();
|
|
199
196
|
this.gitPanel.setMode('history');
|
|
200
197
|
this.gitPanel.setSelection({ source: 'commit' });
|
|
@@ -207,7 +204,6 @@ export const gitFeature = {
|
|
|
207
204
|
},
|
|
208
205
|
|
|
209
206
|
async showGitFileHistory({ filePath = null } = {}) {
|
|
210
|
-
await this.ensureGitControllers?.();
|
|
211
207
|
if (!filePath) {
|
|
212
208
|
this.workspaceRouteController?.showEmptyState?.();
|
|
213
209
|
return;
|
|
@@ -240,7 +236,7 @@ export const gitFeature = {
|
|
|
240
236
|
...data,
|
|
241
237
|
currentFilePath: resolvedCurrentFilePath,
|
|
242
238
|
});
|
|
243
|
-
this.resetPreviewMode();
|
|
239
|
+
this.workspacePreviewController.resetPreviewMode();
|
|
244
240
|
this.elements.markdownToolbar?.classList.add('hidden');
|
|
245
241
|
this.elements.outlineToggle?.classList.toggle('hidden', data.fileKind !== 'markdown');
|
|
246
242
|
|
|
@@ -256,7 +252,7 @@ export const gitFeature = {
|
|
|
256
252
|
}
|
|
257
253
|
|
|
258
254
|
this.elements.outlineToggle?.classList.add('hidden');
|
|
259
|
-
this.renderTextFilePreview
|
|
255
|
+
this.workspacePreviewController.renderTextFilePreview({
|
|
260
256
|
content: data.content,
|
|
261
257
|
filePath: resolvedCurrentFilePath,
|
|
262
258
|
});
|
|
@@ -266,7 +262,7 @@ export const gitFeature = {
|
|
|
266
262
|
console.error('[git-preview] Failed to load file snapshot:', error);
|
|
267
263
|
this.clearStaticPreviewDocument?.();
|
|
268
264
|
this.toastController.show('Failed to load historical file preview');
|
|
269
|
-
this.renderTextFilePreview
|
|
265
|
+
this.workspacePreviewController.renderTextFilePreview({
|
|
270
266
|
content: 'Failed to load historical file preview.',
|
|
271
267
|
filePath: resolvedCurrentFilePath,
|
|
272
268
|
});
|
|
@@ -335,7 +331,6 @@ export const gitFeature = {
|
|
|
335
331
|
},
|
|
336
332
|
|
|
337
333
|
async refreshGitAfterAction({ filePath = null, preferredScope = null } = {}) {
|
|
338
|
-
await this.ensureGitControllers?.();
|
|
339
334
|
await this.gitPanel.refresh({ force: true });
|
|
340
335
|
|
|
341
336
|
const route = this.navigation.getHashRoute();
|
|
@@ -451,6 +446,18 @@ export const gitFeature = {
|
|
|
451
446
|
showToast: true,
|
|
452
447
|
});
|
|
453
448
|
|
|
449
|
+
const structurizrDependencyChanged = [
|
|
450
|
+
...workspaceChange.changedPaths,
|
|
451
|
+
...workspaceChange.deletedPaths,
|
|
452
|
+
...workspaceChange.renamedPaths.flatMap((entry) => [entry.oldPath, entry.newPath]),
|
|
453
|
+
].some((pathValue) => /(?:\.dsl$|(?:^|\/)workspace\.json$)/iu.test(pathValue));
|
|
454
|
+
if (this.currentFilePath && this.isStructurizrWorkspaceFile?.(this.currentFilePath) && structurizrDependencyChanged) {
|
|
455
|
+
this.structurizrPreview?.queueSync({
|
|
456
|
+
filePath: this.currentFilePath,
|
|
457
|
+
source: this.session?.getText?.() ?? '',
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
454
461
|
if (
|
|
455
462
|
event.origin === 'filesystem'
|
|
456
463
|
&& this.currentFilePath
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getUserAvatarTextColor } from '../../domain/room.js';
|
|
2
|
+
|
|
1
3
|
const MAX_INLINE_AVATARS = 5;
|
|
2
4
|
|
|
3
5
|
function compareUserNames(left, right) {
|
|
@@ -11,8 +13,9 @@ function getConnectedPresenceState(context) {
|
|
|
11
13
|
const isDrawioRoute = Boolean(context.currentFilePath && context.isDrawioFile?.(context.currentFilePath));
|
|
12
14
|
const isExcalidrawRoute = Boolean(context.currentFilePath && context.isExcalidrawFile?.(context.currentFilePath));
|
|
13
15
|
const isImageRoute = Boolean(context.currentFilePath && context.isImageFile?.(context.currentFilePath));
|
|
16
|
+
const isPdfRoute = Boolean(context.currentFilePath && context.isPdfFile?.(context.currentFilePath));
|
|
14
17
|
const shouldUseLobbyState = !hasEditorSession
|
|
15
|
-
&& (!context.currentFilePath || isDrawioRoute || isExcalidrawRoute || isImageRoute);
|
|
18
|
+
&& (!context.currentFilePath || isDrawioRoute || isExcalidrawRoute || isImageRoute || isPdfRoute);
|
|
16
19
|
return shouldUseLobbyState
|
|
17
20
|
? context.lobby?.getConnectionState?.() ?? context.connectionState
|
|
18
21
|
: context.connectionState;
|
|
@@ -65,7 +68,7 @@ export const presenceFeature = {
|
|
|
65
68
|
this.globalUsers = users;
|
|
66
69
|
this.syncFollowedUser();
|
|
67
70
|
this.renderAvatars();
|
|
68
|
-
this.renderChat();
|
|
71
|
+
this.renderChat({ messagesChanged: false });
|
|
69
72
|
this.renderPresence();
|
|
70
73
|
this.syncCurrentUserName();
|
|
71
74
|
},
|
|
@@ -126,6 +129,7 @@ export const presenceFeature = {
|
|
|
126
129
|
avatar.className = 'user-avatar';
|
|
127
130
|
avatar.classList.toggle('is-local', user.isLocal);
|
|
128
131
|
avatar.style.backgroundColor = user.color;
|
|
132
|
+
avatar.style.color = getUserAvatarTextColor(user.color);
|
|
129
133
|
avatar.classList.toggle('is-following', user.clientId === this.followedUserClientId);
|
|
130
134
|
|
|
131
135
|
const initial = document.createElement('span');
|
|
@@ -181,8 +185,6 @@ export const presenceFeature = {
|
|
|
181
185
|
overflow.appendChild(overflowLabel);
|
|
182
186
|
avatars.appendChild(overflow);
|
|
183
187
|
}
|
|
184
|
-
|
|
185
|
-
this.renderPresencePanel();
|
|
186
188
|
},
|
|
187
189
|
|
|
188
190
|
openPresencePanel() {
|
|
@@ -196,7 +198,6 @@ export const presenceFeature = {
|
|
|
196
198
|
this.closeToolbarOverflowMenu?.();
|
|
197
199
|
this.renderAvatars();
|
|
198
200
|
this.renderPresence();
|
|
199
|
-
this.renderPresencePanel();
|
|
200
201
|
},
|
|
201
202
|
|
|
202
203
|
closePresencePanel() {
|
|
@@ -207,7 +208,6 @@ export const presenceFeature = {
|
|
|
207
208
|
this.presencePanelOpen = false;
|
|
208
209
|
this.renderAvatars();
|
|
209
210
|
this.renderPresence();
|
|
210
|
-
this.renderPresencePanel();
|
|
211
211
|
},
|
|
212
212
|
|
|
213
213
|
togglePresencePanel() {
|
|
@@ -227,6 +227,9 @@ export const presenceFeature = {
|
|
|
227
227
|
|
|
228
228
|
panel.classList.toggle('hidden', !this.presencePanelOpen);
|
|
229
229
|
panel.setAttribute('aria-hidden', String(!this.presencePanelOpen));
|
|
230
|
+
if (!this.presencePanelOpen) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
230
233
|
|
|
231
234
|
const orderedUsers = getPanelUsers(this.globalUsers, this.followedUserClientId);
|
|
232
235
|
const effectiveConnectionState = getConnectedPresenceState(this);
|
|
@@ -268,6 +271,7 @@ export const presenceFeature = {
|
|
|
268
271
|
const avatar = document.createElement('span');
|
|
269
272
|
avatar.className = 'presence-panel-user-avatar';
|
|
270
273
|
avatar.style.backgroundColor = user.color;
|
|
274
|
+
avatar.style.color = getUserAvatarTextColor(user.color);
|
|
271
275
|
avatar.textContent = user.name.charAt(0).toUpperCase();
|
|
272
276
|
avatar.setAttribute('aria-hidden', 'true');
|
|
273
277
|
|
|
@@ -346,10 +350,11 @@ export const presenceFeature = {
|
|
|
346
350
|
|
|
347
351
|
this.followedUserClientId = clientId;
|
|
348
352
|
this.followedCursorSignature = '';
|
|
349
|
-
this.
|
|
350
|
-
|
|
351
|
-
if (closePanel) {
|
|
353
|
+
if (closePanel && this.presencePanelOpen) {
|
|
352
354
|
this.closePresencePanel();
|
|
355
|
+
} else {
|
|
356
|
+
this.renderAvatars();
|
|
357
|
+
this.renderPresencePanel();
|
|
353
358
|
}
|
|
354
359
|
|
|
355
360
|
if (user.currentFile && user.currentFile !== this.currentFilePath) {
|
|
@@ -382,9 +387,11 @@ export const presenceFeature = {
|
|
|
382
387
|
}
|
|
383
388
|
this.followedUserClientId = null;
|
|
384
389
|
this.followedCursorSignature = '';
|
|
385
|
-
this.
|
|
386
|
-
if (closePanel) {
|
|
390
|
+
if (closePanel && this.presencePanelOpen) {
|
|
387
391
|
this.closePresencePanel();
|
|
392
|
+
} else {
|
|
393
|
+
this.renderAvatars();
|
|
394
|
+
this.renderPresencePanel();
|
|
388
395
|
}
|
|
389
396
|
},
|
|
390
397
|
|
|
@@ -36,6 +36,7 @@ const PREVIEW_HEADING_LINK_ICON = `
|
|
|
36
36
|
* @property {any} themeController
|
|
37
37
|
* @property {any} previewRenderer
|
|
38
38
|
* @property {any} tabActivityLock
|
|
39
|
+
* @property {any} notifications
|
|
39
40
|
* @property {any} toastController
|
|
40
41
|
* @property {any} versionMonitor
|
|
41
42
|
*/
|
|
@@ -53,23 +54,27 @@ function initialize() {
|
|
|
53
54
|
this.layoutController.initialize();
|
|
54
55
|
this.scrollSyncController.initialize();
|
|
55
56
|
this.fileExplorer.initialize();
|
|
57
|
+
this.gitPanel.initialize();
|
|
58
|
+
this.gitDiffView.initialize();
|
|
59
|
+
this.fileHistoryView.initialize();
|
|
56
60
|
this.commentsOverview?.initialize?.();
|
|
57
61
|
this.initializePreviewLayoutObserver();
|
|
58
62
|
this.syncIdentityManagementUi();
|
|
59
63
|
this.syncCurrentUserName();
|
|
60
64
|
this.syncWrapToggle();
|
|
65
|
+
this.syncVimModeToggle();
|
|
61
66
|
this.syncToolbarOverflowVisibility?.();
|
|
62
|
-
this.syncChatNotificationButton();
|
|
63
67
|
this.syncFileHistoryButton({ mode: 'empty' });
|
|
64
68
|
this.renderChat();
|
|
65
69
|
this.elements.chatInput?.setAttribute('maxlength', String(this.lobbyChatMessageMaxLength));
|
|
66
70
|
this.bindEvents();
|
|
71
|
+
this.initializeSidebarResizer?.();
|
|
67
72
|
this.restoreSidebarState();
|
|
68
73
|
this.initializeVersionMonitoring();
|
|
69
74
|
this.tabActivityLock.initialize();
|
|
70
75
|
this.tabActivityLock.tryActivate();
|
|
71
76
|
|
|
72
|
-
window.addEventListener('hashchange', () => this.handleHashChange());
|
|
77
|
+
window.addEventListener('hashchange', () => this.workspaceRouteController.handleHashChange());
|
|
73
78
|
const handleResize = this.createResizeHandler();
|
|
74
79
|
window.addEventListener('resize', () => {
|
|
75
80
|
handleResize();
|
|
@@ -79,9 +84,11 @@ function initialize() {
|
|
|
79
84
|
this.fileExplorerReadyPromise = this.fileExplorer.refresh().then(() => {
|
|
80
85
|
this.fileExplorerReady = true;
|
|
81
86
|
void this.commentsOverview?.refresh?.();
|
|
82
|
-
this.
|
|
87
|
+
if (this.runtimeConfig?.gitEnabled !== false) {
|
|
88
|
+
void this.gitPanel.refresh({ force: true });
|
|
89
|
+
}
|
|
83
90
|
if (this.isTabActive) {
|
|
84
|
-
return this.handleHashChange();
|
|
91
|
+
return this.workspaceRouteController.handleHashChange();
|
|
85
92
|
}
|
|
86
93
|
return undefined;
|
|
87
94
|
});
|
|
@@ -148,15 +155,18 @@ function promptForVersionReload(payload = null) {
|
|
|
148
155
|
|
|
149
156
|
/** @this {UiShellContext} */
|
|
150
157
|
function bindToolbarEvents() {
|
|
158
|
+
const openQuickSwitcher = () => {
|
|
159
|
+
void this.toggleQuickSwitcher();
|
|
160
|
+
this.closeToolbarOverflowMenu?.();
|
|
161
|
+
};
|
|
162
|
+
|
|
151
163
|
this.elements.shareButton?.addEventListener('click', () => {
|
|
152
164
|
void this.copyCurrentLink();
|
|
153
165
|
this.closeToolbarOverflowMenu?.();
|
|
154
166
|
});
|
|
155
167
|
|
|
156
|
-
this.elements.
|
|
157
|
-
|
|
158
|
-
this.closeToolbarOverflowMenu?.();
|
|
159
|
-
});
|
|
168
|
+
this.elements.toolbarSearchButton?.addEventListener('click', openQuickSwitcher);
|
|
169
|
+
this.elements.searchFilesButton?.addEventListener('click', openQuickSwitcher);
|
|
160
170
|
|
|
161
171
|
this.elements.exportDocxButton?.addEventListener('click', () => {
|
|
162
172
|
void this.handleExportRequest?.('docx');
|
|
@@ -252,15 +262,23 @@ function bindEvents() {
|
|
|
252
262
|
this.closeToolbarOverflowMenu?.();
|
|
253
263
|
});
|
|
254
264
|
|
|
265
|
+
this.elements.chatNotificationButton?.addEventListener('click', () => {
|
|
266
|
+
void this.handleChatNotificationToggle();
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
this.elements.chatNotificationMuteButton?.addEventListener('click', () => {
|
|
270
|
+
this.toggleChatNotificationMute();
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
this.elements.chatCloseButton?.addEventListener('click', () => {
|
|
274
|
+
this.closeChatPanel({ restoreFocus: true });
|
|
275
|
+
});
|
|
276
|
+
|
|
255
277
|
this.elements.chatForm?.addEventListener('submit', (event) => {
|
|
256
278
|
event.preventDefault();
|
|
257
279
|
this.handleChatSubmit();
|
|
258
280
|
});
|
|
259
281
|
|
|
260
|
-
this.elements.chatNotificationButton?.addEventListener('click', () => {
|
|
261
|
-
void this.handleChatNotificationToggle();
|
|
262
|
-
});
|
|
263
|
-
|
|
264
282
|
bindToolbarEvents.call(this);
|
|
265
283
|
bindDialogEvents.call(this);
|
|
266
284
|
|
|
@@ -280,6 +298,10 @@ function bindEvents() {
|
|
|
280
298
|
this.toggleLineWrapping();
|
|
281
299
|
});
|
|
282
300
|
|
|
301
|
+
this.elements.toggleVimModeButton?.addEventListener('click', () => {
|
|
302
|
+
this.toggleVimMode();
|
|
303
|
+
});
|
|
304
|
+
|
|
283
305
|
this.elements.userCount?.addEventListener('click', (event) => {
|
|
284
306
|
event.preventDefault();
|
|
285
307
|
this.togglePresencePanel?.();
|
|
@@ -296,7 +318,8 @@ function bindEvents() {
|
|
|
296
318
|
});
|
|
297
319
|
|
|
298
320
|
this.elements.toolbarOverflowMenu?.addEventListener('click', (event) => {
|
|
299
|
-
|
|
321
|
+
const button = event.target instanceof Element ? event.target.closest('button') : null;
|
|
322
|
+
if (button && button !== this.elements.toggleVimModeButton) {
|
|
300
323
|
this.closeToolbarOverflowMenu();
|
|
301
324
|
}
|
|
302
325
|
});
|
|
@@ -372,7 +395,7 @@ function handleDocumentPointerDown(event) {
|
|
|
372
395
|
return;
|
|
373
396
|
}
|
|
374
397
|
|
|
375
|
-
this.closeChatPanel();
|
|
398
|
+
this.closeChatPanel({ restoreFocus: false });
|
|
376
399
|
}
|
|
377
400
|
|
|
378
401
|
/** @this {UiShellContext} */
|
|
@@ -388,7 +411,7 @@ function handleDocumentKeydown(event) {
|
|
|
388
411
|
}
|
|
389
412
|
|
|
390
413
|
if (event.key === 'Escape' && this.chatIsOpen) {
|
|
391
|
-
this.closeChatPanel();
|
|
414
|
+
this.closeChatPanel({ restoreFocus: true });
|
|
392
415
|
return;
|
|
393
416
|
}
|
|
394
417
|
|
|
@@ -626,7 +649,7 @@ function handlePreviewContentClick(event) {
|
|
|
626
649
|
const wikiLink = event.target.closest('a.wiki-link[data-wiki-target]');
|
|
627
650
|
if (wikiLink) {
|
|
628
651
|
event.preventDefault();
|
|
629
|
-
this.handleWikiLinkClick(wikiLink.dataset.wikiTarget);
|
|
652
|
+
this.wikiLinkFileController.handleWikiLinkClick(wikiLink.dataset.wikiTarget);
|
|
630
653
|
return;
|
|
631
654
|
}
|
|
632
655
|
|
|
@@ -714,7 +737,12 @@ function toggleToolbarOverflowMenu() {
|
|
|
714
737
|
/** @this {UiShellContext} */
|
|
715
738
|
function handleThemeChange(theme) {
|
|
716
739
|
this.previewRenderer.applyTheme(theme);
|
|
717
|
-
if (
|
|
740
|
+
if (
|
|
741
|
+
!this.isExcalidrawFile(this.currentFilePath)
|
|
742
|
+
&& !this.isImageFile?.(this.currentFilePath)
|
|
743
|
+
&& !this.isPdfFile?.(this.currentFilePath)
|
|
744
|
+
&& !this.isStructurizrWorkspaceFile?.(this.currentFilePath)
|
|
745
|
+
) {
|
|
718
746
|
this.previewRenderer.queueRender();
|
|
719
747
|
}
|
|
720
748
|
this.session?.applyTheme(theme);
|
|
@@ -731,6 +759,7 @@ function handleConnectionChange(state) {
|
|
|
731
759
|
});
|
|
732
760
|
}
|
|
733
761
|
this.renderPresence();
|
|
762
|
+
this.renderChat({ messagesChanged: false });
|
|
734
763
|
|
|
735
764
|
if (state.unreachable && !this.connectionHelpShown) {
|
|
736
765
|
this.connectionHelpShown = true;
|
|
@@ -755,6 +784,35 @@ function getStoredLineWrapping() {
|
|
|
755
784
|
return this.preferences.getLineWrappingEnabled();
|
|
756
785
|
}
|
|
757
786
|
|
|
787
|
+
/** @this {UiShellContext} */
|
|
788
|
+
function toggleVimMode() {
|
|
789
|
+
const currentState = this.session?.isVimModeEnabled?.() ?? this.getStoredVimMode();
|
|
790
|
+
const nextState = !currentState;
|
|
791
|
+
|
|
792
|
+
this.session?.setVimMode?.(nextState);
|
|
793
|
+
this.preferences.setVimModeEnabled(nextState);
|
|
794
|
+
this.syncVimModeToggle(nextState);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/** @this {UiShellContext} */
|
|
798
|
+
function getStoredVimMode() {
|
|
799
|
+
return this.preferences.getVimModeEnabled();
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/** @this {UiShellContext} */
|
|
803
|
+
function syncVimModeToggle(state) {
|
|
804
|
+
const enabled = state ?? this.session?.isVimModeEnabled?.() ?? this.getStoredVimMode();
|
|
805
|
+
const label = this.elements.vimModeToggleLabel;
|
|
806
|
+
const button = this.elements.toggleVimModeButton;
|
|
807
|
+
const nextLabel = enabled ? 'On' : 'Off';
|
|
808
|
+
if (label) label.textContent = nextLabel;
|
|
809
|
+
if (button) {
|
|
810
|
+
button.setAttribute('aria-label', `${enabled ? 'Disable' : 'Enable'} Vim keybindings`);
|
|
811
|
+
button.setAttribute('title', `${enabled ? 'Disable' : 'Enable'} Vim keybindings`);
|
|
812
|
+
button.setAttribute('aria-pressed', String(enabled));
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
758
816
|
/** @this {UiShellContext} */
|
|
759
817
|
function syncWrapToggle(state) {
|
|
760
818
|
const enabled = state ?? this.session?.isLineWrappingEnabled() ?? this.getStoredLineWrapping();
|
|
@@ -818,6 +876,7 @@ export const uiFeatureShellMethods = {
|
|
|
818
876
|
copyPreviewHeadingLink,
|
|
819
877
|
createPreviewHeadingLinkUrl,
|
|
820
878
|
getStoredLineWrapping,
|
|
879
|
+
getStoredVimMode,
|
|
821
880
|
handleConnectionChange,
|
|
822
881
|
handleDocumentKeydown,
|
|
823
882
|
handleDocumentPointerDown,
|
|
@@ -838,7 +897,9 @@ export const uiFeatureShellMethods = {
|
|
|
838
897
|
syncPreviewHeadingLinkButtons,
|
|
839
898
|
syncVisualViewportBounds,
|
|
840
899
|
syncToolbarOverflowVisibility,
|
|
900
|
+
syncVimModeToggle,
|
|
841
901
|
syncWrapToggle,
|
|
842
902
|
toggleToolbarOverflowMenu,
|
|
843
903
|
toggleLineWrapping,
|
|
904
|
+
toggleVimMode,
|
|
844
905
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {object} UiSidebarContext
|
|
3
3
|
* @property {string} activeSidebarTab
|
|
4
|
-
* @property {{ sidebar?: HTMLElement | null, sidebarBackdrop?: HTMLElement | null, filesSidebarTab?: HTMLElement | null, commentsSidebarTab?: HTMLElement | null, gitSidebarTab?: HTMLElement | null, fileSearch?: HTMLElement | null, gitSearch?: HTMLElement | null, commentOverviewPanel?: HTMLElement | null }} elements
|
|
4
|
+
* @property {{ sidebar?: HTMLElement | null, sidebarBackdrop?: HTMLElement | null, sidebarResizer?: HTMLElement | null, filesSidebarTab?: HTMLElement | null, commentsSidebarTab?: HTMLElement | null, gitSidebarTab?: HTMLElement | null, fileSearch?: HTMLElement | null, gitSearch?: HTMLElement | null, commentOverviewPanel?: HTMLElement | null }} elements
|
|
5
5
|
* @property {{ setSidebarVisible(showSidebar: boolean): void, getSidebarVisible(): string | null | undefined }} preferences
|
|
6
6
|
* @property {{ setActive(active: boolean): void }} gitPanel
|
|
7
7
|
* @property {boolean} gitRepoAvailable
|
|
@@ -11,6 +11,78 @@
|
|
|
11
11
|
* @property {(showSidebar: boolean) => void} setSidebarVisibility
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
const SIDEBAR_DEFAULT_WIDTH = 260;
|
|
15
|
+
const SIDEBAR_MIN_WIDTH = 220;
|
|
16
|
+
const SIDEBAR_MAX_WIDTH = 420;
|
|
17
|
+
const SIDEBAR_KEYBOARD_STEP = 16;
|
|
18
|
+
|
|
19
|
+
/** @this {UiSidebarContext} */
|
|
20
|
+
function initializeSidebarResizer() {
|
|
21
|
+
const sidebar = this.elements.sidebar;
|
|
22
|
+
const resizer = this.elements.sidebarResizer;
|
|
23
|
+
if (!sidebar || !resizer) return;
|
|
24
|
+
|
|
25
|
+
let sidebarWidth = SIDEBAR_DEFAULT_WIDTH;
|
|
26
|
+
let pointerId = null;
|
|
27
|
+
let startX = 0;
|
|
28
|
+
let startWidth = SIDEBAR_DEFAULT_WIDTH;
|
|
29
|
+
|
|
30
|
+
const clampWidth = (width) => Math.round(Math.max(SIDEBAR_MIN_WIDTH, Math.min(SIDEBAR_MAX_WIDTH, width)));
|
|
31
|
+
const applyWidth = (width) => {
|
|
32
|
+
sidebarWidth = clampWidth(width);
|
|
33
|
+
sidebar.style.setProperty('--sidebar-width', `${sidebarWidth}px`);
|
|
34
|
+
resizer.setAttribute('aria-valuenow', String(sidebarWidth));
|
|
35
|
+
};
|
|
36
|
+
const finishResize = (event) => {
|
|
37
|
+
if (event?.pointerId != null && event.pointerId !== pointerId) return;
|
|
38
|
+
if (pointerId === null) return;
|
|
39
|
+
|
|
40
|
+
pointerId = null;
|
|
41
|
+
sidebar.classList.remove('is-resizing');
|
|
42
|
+
document.body.style.cursor = '';
|
|
43
|
+
document.body.style.userSelect = '';
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
applyWidth(SIDEBAR_DEFAULT_WIDTH);
|
|
47
|
+
|
|
48
|
+
resizer.addEventListener('pointerdown', (event) => {
|
|
49
|
+
if (this.isMobileViewport() || sidebar.classList.contains('collapsed')) return;
|
|
50
|
+
|
|
51
|
+
pointerId = event.pointerId;
|
|
52
|
+
startX = event.clientX;
|
|
53
|
+
startWidth = sidebar.getBoundingClientRect().width || sidebarWidth;
|
|
54
|
+
sidebar.classList.add('is-resizing');
|
|
55
|
+
document.body.style.cursor = 'col-resize';
|
|
56
|
+
document.body.style.userSelect = 'none';
|
|
57
|
+
resizer.setPointerCapture?.(event.pointerId);
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
resizer.addEventListener('pointermove', (event) => {
|
|
62
|
+
if (event.pointerId !== pointerId) return;
|
|
63
|
+
applyWidth(startWidth + event.clientX - startX);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
resizer.addEventListener('pointerup', finishResize);
|
|
67
|
+
resizer.addEventListener('pointercancel', finishResize);
|
|
68
|
+
resizer.addEventListener('lostpointercapture', finishResize);
|
|
69
|
+
|
|
70
|
+
resizer.addEventListener('keydown', (event) => {
|
|
71
|
+
if (this.isMobileViewport() || sidebar.classList.contains('collapsed')) return;
|
|
72
|
+
|
|
73
|
+
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
applyWidth(sidebarWidth + (event.key === 'ArrowRight' ? SIDEBAR_KEYBOARD_STEP : -SIDEBAR_KEYBOARD_STEP));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (event.key === 'Home' || event.key === 'End') {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
applyWidth(event.key === 'Home' ? SIDEBAR_MIN_WIDTH : SIDEBAR_MAX_WIDTH);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
14
86
|
/** @this {UiSidebarContext} */
|
|
15
87
|
function isMobileViewport() {
|
|
16
88
|
return this.mobileBreakpointQuery.matches;
|
|
@@ -108,6 +180,7 @@ function setSidebarTab(tab) {
|
|
|
108
180
|
export const uiFeatureSidebarMethods = {
|
|
109
181
|
applySidebarVisibility,
|
|
110
182
|
closeSidebarOnMobile,
|
|
183
|
+
initializeSidebarResizer,
|
|
111
184
|
isMobileViewport,
|
|
112
185
|
restoreSidebarState,
|
|
113
186
|
setSidebarTab,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* @property {{ show(message: string): void }} toastController
|
|
17
17
|
* @property {{ tryActivate(options?: { takeover?: boolean }): void }} tabActivityLock
|
|
18
18
|
* @property {{ prepareFileDisconnect(filePath: string): Promise<void> }} excalidrawEmbed
|
|
19
|
-
* @property {()
|
|
19
|
+
* @property {{ handleHashChange(): Promise<void> }} workspaceRouteController
|
|
20
20
|
* @property {() => boolean} isExcalidrawFile
|
|
21
21
|
* @property {() => void} promptForDisplayNameIfNeeded
|
|
22
22
|
* @property {() => void} renderChat
|
|
@@ -45,7 +45,7 @@ function handleTabActivated({ takeover = false } = {}) {
|
|
|
45
45
|
|
|
46
46
|
if (wasInactive) {
|
|
47
47
|
if (this.fileExplorerReady) {
|
|
48
|
-
void this.handleHashChange();
|
|
48
|
+
void this.workspaceRouteController.handleHashChange();
|
|
49
49
|
}
|
|
50
50
|
this.promptForDisplayNameIfNeeded();
|
|
51
51
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isMarkdownFilePath } from '../../../domain/file-kind.js';
|
|
2
|
+
import { pickFiles } from '../../browser-utils.js';
|
|
2
3
|
import {
|
|
3
4
|
getMarkdownBlockActionLabel,
|
|
4
5
|
getMarkdownBlockMenuActions,
|
|
@@ -91,7 +92,6 @@ function renderMarkdownToolbarMarkup(activeAction) {
|
|
|
91
92
|
* @property {{ show(message: string): void }} toastController
|
|
92
93
|
* @property {{ uploadImageAttachment(payload: { file: File, fileName: string, sourcePath: string }): Promise<{ markdown?: string, path?: string }>} } vaultApiClient
|
|
93
94
|
* @property {{ applyMarkdownToolbarAction(action: string): boolean, insertText(text: string): void, runEditorCommand?(commandId: string): boolean } | null} session
|
|
94
|
-
* @property {() => Promise<File | null>} pickImageFile
|
|
95
95
|
* @property {(file: File) => Promise<boolean>} handleEditorImageInsert
|
|
96
96
|
* @property {() => Promise<void>} handleToolbarImageInsert
|
|
97
97
|
*/
|
|
@@ -395,7 +395,7 @@ function runEditorCommand(commandId) {
|
|
|
395
395
|
|
|
396
396
|
/** @this {UiToolbarContext} */
|
|
397
397
|
async function handleToolbarImageInsert() {
|
|
398
|
-
const file = await
|
|
398
|
+
const [file] = await pickFiles({ accept: IMAGE_FILE_PICKER_ACCEPT });
|
|
399
399
|
if (!file) {
|
|
400
400
|
return;
|
|
401
401
|
}
|
|
@@ -403,55 +403,6 @@ async function handleToolbarImageInsert() {
|
|
|
403
403
|
await this.handleEditorImageInsert(file);
|
|
404
404
|
}
|
|
405
405
|
|
|
406
|
-
/** @this {UiToolbarContext} */
|
|
407
|
-
function pickImageFile() {
|
|
408
|
-
return new Promise((resolve) => {
|
|
409
|
-
const input = document.createElement('input');
|
|
410
|
-
input.type = 'file';
|
|
411
|
-
input.accept = IMAGE_FILE_PICKER_ACCEPT;
|
|
412
|
-
input.style.position = 'fixed';
|
|
413
|
-
input.style.left = '-9999px';
|
|
414
|
-
document.body.appendChild(input);
|
|
415
|
-
let settled = false;
|
|
416
|
-
let focusTimer = null;
|
|
417
|
-
|
|
418
|
-
const cleanup = (value) => {
|
|
419
|
-
if (settled) {
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
settled = true;
|
|
424
|
-
if (focusTimer) {
|
|
425
|
-
window.clearTimeout(focusTimer);
|
|
426
|
-
}
|
|
427
|
-
window.removeEventListener('focus', handleWindowFocus);
|
|
428
|
-
input.remove();
|
|
429
|
-
resolve(value);
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
const handleWindowFocus = () => {
|
|
433
|
-
focusTimer = window.setTimeout(() => {
|
|
434
|
-
if (settled || input.files?.length) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
cleanup(null);
|
|
439
|
-
}, 250);
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
input.addEventListener('change', () => {
|
|
443
|
-
cleanup(input.files?.[0] ?? null);
|
|
444
|
-
}, { once: true });
|
|
445
|
-
|
|
446
|
-
input.addEventListener('cancel', () => {
|
|
447
|
-
cleanup(null);
|
|
448
|
-
}, { once: true });
|
|
449
|
-
|
|
450
|
-
window.addEventListener('focus', handleWindowFocus, { once: true });
|
|
451
|
-
input.click();
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
|
|
455
406
|
/** @this {UiToolbarContext} */
|
|
456
407
|
async function handleEditorImageInsert(file) {
|
|
457
408
|
if (!this.session || !isMarkdownFilePath(this.currentFilePath)) {
|
|
@@ -526,7 +477,6 @@ export const uiFeatureToolbarMethods = {
|
|
|
526
477
|
openMarkdownBlockMenu,
|
|
527
478
|
positionMarkdownBlockMenu,
|
|
528
479
|
renderMarkdownBlockMenuPopover,
|
|
529
|
-
pickImageFile,
|
|
530
480
|
renderMarkdownToolbar,
|
|
531
481
|
runEditorCommand,
|
|
532
482
|
setActiveMarkdownBlockAction,
|