collabmd 0.1.44 → 0.1.45

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.
Files changed (170) hide show
  1. package/dist/client/assets/{chunk-AXR3VHVW-0GTk_evH.js → chunk-ERSWUTIN-ME9RVNel.js} +3 -3
  2. package/dist/client/assets/{chunk-CZQZEIFA-DT3N9fo7.js → chunk-YGJVY4SA-CjSe7Bx7.js} +2 -2
  3. package/dist/client/assets/{comment-threads-D-iKphIp.js → comment-threads-DDegmaFO.js} +1 -1
  4. package/dist/client/assets/drawio-editor-ClE8jpoG.js +9 -0
  5. package/dist/client/assets/drawioEditor-CXaTM9Ds.js +2 -0
  6. package/dist/client/assets/editor-session-GTwZS6Df.js +16 -0
  7. package/dist/client/assets/embedded-editor-base-CiNEc8vy.css +1 -0
  8. package/dist/client/assets/{en-GADW4C6J-DQ6zyCEM.js → en-7NFCYGKX-BrgYZAEe.js} +1 -1
  9. package/dist/client/assets/{excalidraw-editor-BHu6k8d4.js → excalidraw-editor-BZVM81BO.js} +2 -2
  10. package/dist/client/assets/excalidraw-editor-CyGwOhLz.css +1 -0
  11. package/dist/client/assets/excalidraw-scene-C8n9CHsK.js +176 -0
  12. package/dist/client/assets/excalidrawEditor-DxJanCze.js +2 -0
  13. package/dist/client/assets/export-page-CUfws2T-.js +39 -0
  14. package/dist/client/assets/exportDocument-BCuxqXDY.js +2 -0
  15. package/dist/client/assets/exportDocument-DV-OX74E.css +1 -0
  16. package/dist/client/assets/image-QXRYHUNP-lfTHE3bb.js +1 -0
  17. package/dist/client/assets/index-C3YnUgMD.css +1 -0
  18. package/dist/client/assets/index-D2wXraJ1.js +2 -0
  19. package/dist/client/assets/main-DtiGz7uI.js +795 -0
  20. package/dist/client/assets/modulepreload-polyfill-P2Xu9kJm.js +1 -0
  21. package/dist/client/assets/preview-diagram-utils-txBCoW8d.js +1 -0
  22. package/dist/client/assets/quick-switcher-controller-shW_6vPY.js +12 -0
  23. package/dist/client/assets/room-CQLoqtMo.js +1 -0
  24. package/dist/client/assets/runtime-config-DSGmGE9V.js +1 -0
  25. package/dist/client/assets/vault-api-client-C6bcGwy-.js +5 -0
  26. package/dist/client/assets/{yjs-provider-reset-guard-Cox4nxwu.js → yjs-provider-reset-guard-DE0vINDP.js} +1 -1
  27. package/dist/client/drawio-editor.html +3 -2
  28. package/dist/client/excalidraw-editor.html +3 -2
  29. package/dist/client/export-document.html +4 -3
  30. package/dist/client/index.html +97 -27
  31. package/package.json +10 -12
  32. package/src/client/app/drawio-editor-entry.js +0 -3
  33. package/src/client/app/drawio-editor.html +1 -0
  34. package/src/client/app/excalidraw-editor-entry.js +0 -3
  35. package/src/client/app/excalidraw-editor.html +1 -0
  36. package/src/client/app/export-document-entry.js +0 -3
  37. package/src/client/app/export-document.html +1 -0
  38. package/src/client/app/index.html +94 -24
  39. package/src/client/app/main-entry.js +0 -5
  40. package/src/client/application/app-shell/chat-feature.js +180 -124
  41. package/src/client/application/app-shell/comments-feature.js +1 -1
  42. package/src/client/application/app-shell/git-feature.js +4 -9
  43. package/src/client/application/app-shell/presence-feature.js +16 -10
  44. package/src/client/application/app-shell/ui-feature-shell.js +33 -15
  45. package/src/client/application/app-shell/ui-feature-sidebar.js +74 -1
  46. package/src/client/application/app-shell/ui-feature-tab-activity.js +2 -2
  47. package/src/client/application/app-shell/workspace-feature.js +22 -83
  48. package/src/client/application/app-shell-elements.js +7 -1
  49. package/src/client/application/diagram-chrome.js +161 -166
  50. package/src/client/application/diagram-preview-export.js +7 -34
  51. package/src/client/application/diagram-preview-hydrator.js +1 -19
  52. package/src/client/application/markdown-frontmatter.js +0 -2
  53. package/src/client/application/mermaid-preview-hydrator.js +1 -14
  54. package/src/client/application/plantuml-preview-hydrator.js +0 -10
  55. package/src/client/application/preview-diagram-utils.js +31 -2
  56. package/src/client/application/preview-render-compiler.js +2 -1
  57. package/src/client/application/preview-renderer.js +2 -2
  58. package/src/client/application/quick-switcher-loader.js +3 -1
  59. package/src/client/application/workspace-preview-controller.js +0 -3
  60. package/src/client/bootstrap/collabmd-app-shell.js +125 -39
  61. package/src/client/domain/excalidraw-collaboration.js +0 -2
  62. package/src/client/domain/room.js +38 -0
  63. package/src/client/export/export-pipeline.js +6 -34
  64. package/src/client/infrastructure/auth-client.js +4 -10
  65. package/src/client/infrastructure/browser-notification-port.js +33 -20
  66. package/src/client/infrastructure/browser-preferences-port.js +36 -9
  67. package/src/client/infrastructure/editor-view-adapter.js +87 -3
  68. package/src/client/infrastructure/lobby-presence.js +1 -0
  69. package/src/client/infrastructure/vault-api-client.js +25 -0
  70. package/src/client/infrastructure/workspace-sync-client.js +13 -1
  71. package/src/client/presentation/comment-overview-controller.js +18 -53
  72. package/src/client/presentation/comment-ui/comment-ui-card.js +1 -12
  73. package/src/client/presentation/comment-ui/comment-ui-layout.js +242 -219
  74. package/src/client/presentation/comment-ui/comment-ui-render.js +32 -45
  75. package/src/client/presentation/comment-ui/comment-ui-shared.js +65 -14
  76. package/src/client/presentation/comment-ui-controller.js +5 -1
  77. package/src/client/presentation/file-action-controller.js +32 -0
  78. package/src/client/presentation/file-explorer-controller.js +33 -3
  79. package/src/client/presentation/file-explorer-view.js +49 -5
  80. package/src/client/presentation/file-tree-state.js +10 -4
  81. package/src/client/presentation/quick-switcher-controller.js +243 -72
  82. package/src/client/presentation/quick-switcher-text-search.js +2 -2
  83. package/src/client/presentation/toast-controller.js +3 -0
  84. package/src/client/styles/components/feedback.css +6 -0
  85. package/src/client/styles/features/collaboration-chat.css +49 -53
  86. package/src/client/styles/features/collaboration-presence.css +9 -7
  87. package/src/client/styles/features/comment-card.css +25 -11
  88. package/src/client/styles/features/comment-overlays.css +0 -4
  89. package/src/client/styles/features/comment-overview.css +44 -21
  90. package/src/client/styles/features/comments-drawer.css +2 -100
  91. package/src/client/styles/features/diagram-preview.css +5 -18
  92. package/src/client/styles/features/embedded-preview.css +8 -33
  93. package/src/client/styles/features/quick-switcher.css +8 -0
  94. package/src/client/styles/foundation/tokens.css +1 -0
  95. package/src/client/styles/layout/editor-page.css +40 -0
  96. package/src/client/styles/layout/responsive.css +31 -1
  97. package/src/client/styles/layout/shell.css +25 -6
  98. package/src/client/styles/layout/sidebar.css +47 -15
  99. package/src/client/styles/overrides/codemirror.css +217 -15
  100. package/src/server/application/workspace-reconciliation.js +1 -1
  101. package/src/server/create-app-server.js +2 -3
  102. package/src/server/domain/bases/base-query-service.js +1 -77
  103. package/src/server/domain/comment-overview.js +10 -3
  104. package/src/server/domain/docx-exporter.js +24 -33
  105. package/src/server/domain/ripgrep-search-service.js +3 -1
  106. package/src/server/domain/workspace-state.js +32 -11
  107. package/src/server/infrastructure/git/diff-service.js +24 -13
  108. package/src/server/infrastructure/git/git-service.js +40 -10
  109. package/src/server/infrastructure/git/history-service.js +42 -29
  110. package/src/server/infrastructure/git/path-utils.js +1 -1
  111. package/src/server/infrastructure/git/responses.js +0 -95
  112. package/src/server/infrastructure/github/github-app-client.js +22 -15
  113. package/src/server/infrastructure/http/create-request-handler.js +2 -8
  114. package/src/server/infrastructure/http/create-vault-api-command-handler.js +5 -5
  115. package/src/server/infrastructure/http/http-errors.js +7 -1
  116. package/dist/client/assets/bases-preview-controller-2pLHk0uk.js +0 -143
  117. package/dist/client/assets/button-BCEiw4Rw.js +0 -1
  118. package/dist/client/assets/diagram-action-icons-aa_KOv9h.js +0 -36
  119. package/dist/client/assets/drawio-editor-DDvFoarP.js +0 -9
  120. package/dist/client/assets/drawio-embed-controller-BD1GTRwn.js +0 -1
  121. package/dist/client/assets/drawioEditor-Bu5grlH5.js +0 -2
  122. package/dist/client/assets/editor-session-DGlpiAsK.js +0 -16
  123. package/dist/client/assets/embedded-editor-base-C9roKYpW.css +0 -1
  124. package/dist/client/assets/excalidraw-editor-Cr_184EF.css +0 -1
  125. package/dist/client/assets/excalidraw-embed-controller-y2fenN_g.js +0 -1
  126. package/dist/client/assets/excalidraw-embed-reconciler-DGiagExg.js +0 -1
  127. package/dist/client/assets/excalidraw-scene-BvsQ6mLP.js +0 -176
  128. package/dist/client/assets/excalidrawEditor-4vFE--Uw.js +0 -2
  129. package/dist/client/assets/export-page-Cby8JzPO.js +0 -39
  130. package/dist/client/assets/exportDocument-C9v-bc7I.css +0 -1
  131. package/dist/client/assets/exportDocument-CRHCfsdo.js +0 -2
  132. package/dist/client/assets/file-history-view-controller-BDjEV9xJ.js +0 -112
  133. package/dist/client/assets/git-diff-view-controller-DgdM1aqb.js +0 -150
  134. package/dist/client/assets/git-panel-controller-BDTR2HVp.js +0 -207
  135. package/dist/client/assets/image-XGD7JQR6-XDUWHRpO.js +0 -1
  136. package/dist/client/assets/index-7xOyXDhP.css +0 -1
  137. package/dist/client/assets/index-Bz1KuQ6y.js +0 -2
  138. package/dist/client/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  139. package/dist/client/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  140. package/dist/client/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  141. package/dist/client/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  142. package/dist/client/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  143. package/dist/client/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  144. package/dist/client/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  145. package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  146. package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  147. package/dist/client/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  148. package/dist/client/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  149. package/dist/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  150. package/dist/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  151. package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  152. package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  153. package/dist/client/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  154. package/dist/client/assets/main-Ci07m9oP.js +0 -152
  155. package/dist/client/assets/preview-diagram-utils-n_bbJA9V.js +0 -1
  156. package/dist/client/assets/quick-switcher-controller-CoiYvllm.js +0 -12
  157. package/dist/client/assets/room-CDrmIdDt.js +0 -1
  158. package/dist/client/assets/runtime-config-CDgeuPWN.js +0 -1
  159. package/dist/client/assets/runtime-config-loader-BHGniHP5.js +0 -1
  160. package/dist/client/assets/runtime-paths-DvpihCEq.js +0 -1
  161. package/dist/client/assets/segmented-control-DJrHSz8M.js +0 -1
  162. package/dist/client/assets/vault-api-client-sLB2bo56.js +0 -1
  163. package/dist/client/assets/vault-paths-CVkuh0j-.js +0 -5
  164. package/src/client/bootstrap/lazy-controller-feature.js +0 -433
  165. package/src/client/infrastructure/backlinks-api-client.js +0 -16
  166. package/src/client/infrastructure/plantuml-api-client.js +0 -19
  167. package/src/client/infrastructure/runtime-config-loader.js +0 -56
  168. package/src/server/infrastructure/git/command-runner.js +0 -49
  169. package/src/server/infrastructure/git/errors.js +0 -8
  170. package/src/server/infrastructure/http/create-esm-proxy-handler.js +0 -130
@@ -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,26 @@ 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();
61
65
  this.syncToolbarOverflowVisibility?.();
62
- this.syncChatNotificationButton();
63
66
  this.syncFileHistoryButton({ mode: 'empty' });
64
67
  this.renderChat();
65
68
  this.elements.chatInput?.setAttribute('maxlength', String(this.lobbyChatMessageMaxLength));
66
69
  this.bindEvents();
70
+ this.initializeSidebarResizer?.();
67
71
  this.restoreSidebarState();
68
72
  this.initializeVersionMonitoring();
69
73
  this.tabActivityLock.initialize();
70
74
  this.tabActivityLock.tryActivate();
71
75
 
72
- window.addEventListener('hashchange', () => this.handleHashChange());
76
+ window.addEventListener('hashchange', () => this.workspaceRouteController.handleHashChange());
73
77
  const handleResize = this.createResizeHandler();
74
78
  window.addEventListener('resize', () => {
75
79
  handleResize();
@@ -79,9 +83,11 @@ function initialize() {
79
83
  this.fileExplorerReadyPromise = this.fileExplorer.refresh().then(() => {
80
84
  this.fileExplorerReady = true;
81
85
  void this.commentsOverview?.refresh?.();
82
- this.scheduleGitControllerPrewarm?.();
86
+ if (this.runtimeConfig?.gitEnabled !== false) {
87
+ void this.gitPanel.refresh({ force: true });
88
+ }
83
89
  if (this.isTabActive) {
84
- return this.handleHashChange();
90
+ return this.workspaceRouteController.handleHashChange();
85
91
  }
86
92
  return undefined;
87
93
  });
@@ -148,15 +154,18 @@ function promptForVersionReload(payload = null) {
148
154
 
149
155
  /** @this {UiShellContext} */
150
156
  function bindToolbarEvents() {
157
+ const openQuickSwitcher = () => {
158
+ void this.toggleQuickSwitcher();
159
+ this.closeToolbarOverflowMenu?.();
160
+ };
161
+
151
162
  this.elements.shareButton?.addEventListener('click', () => {
152
163
  void this.copyCurrentLink();
153
164
  this.closeToolbarOverflowMenu?.();
154
165
  });
155
166
 
156
- this.elements.searchFilesButton?.addEventListener('click', () => {
157
- void this.toggleQuickSwitcher();
158
- this.closeToolbarOverflowMenu?.();
159
- });
167
+ this.elements.toolbarSearchButton?.addEventListener('click', openQuickSwitcher);
168
+ this.elements.searchFilesButton?.addEventListener('click', openQuickSwitcher);
160
169
 
161
170
  this.elements.exportDocxButton?.addEventListener('click', () => {
162
171
  void this.handleExportRequest?.('docx');
@@ -252,15 +261,23 @@ function bindEvents() {
252
261
  this.closeToolbarOverflowMenu?.();
253
262
  });
254
263
 
264
+ this.elements.chatNotificationButton?.addEventListener('click', () => {
265
+ void this.handleChatNotificationToggle();
266
+ });
267
+
268
+ this.elements.chatNotificationMuteButton?.addEventListener('click', () => {
269
+ this.toggleChatNotificationMute();
270
+ });
271
+
272
+ this.elements.chatCloseButton?.addEventListener('click', () => {
273
+ this.closeChatPanel({ restoreFocus: true });
274
+ });
275
+
255
276
  this.elements.chatForm?.addEventListener('submit', (event) => {
256
277
  event.preventDefault();
257
278
  this.handleChatSubmit();
258
279
  });
259
280
 
260
- this.elements.chatNotificationButton?.addEventListener('click', () => {
261
- void this.handleChatNotificationToggle();
262
- });
263
-
264
281
  bindToolbarEvents.call(this);
265
282
  bindDialogEvents.call(this);
266
283
 
@@ -372,7 +389,7 @@ function handleDocumentPointerDown(event) {
372
389
  return;
373
390
  }
374
391
 
375
- this.closeChatPanel();
392
+ this.closeChatPanel({ restoreFocus: false });
376
393
  }
377
394
 
378
395
  /** @this {UiShellContext} */
@@ -388,7 +405,7 @@ function handleDocumentKeydown(event) {
388
405
  }
389
406
 
390
407
  if (event.key === 'Escape' && this.chatIsOpen) {
391
- this.closeChatPanel();
408
+ this.closeChatPanel({ restoreFocus: true });
392
409
  return;
393
410
  }
394
411
 
@@ -626,7 +643,7 @@ function handlePreviewContentClick(event) {
626
643
  const wikiLink = event.target.closest('a.wiki-link[data-wiki-target]');
627
644
  if (wikiLink) {
628
645
  event.preventDefault();
629
- this.handleWikiLinkClick(wikiLink.dataset.wikiTarget);
646
+ this.wikiLinkFileController.handleWikiLinkClick(wikiLink.dataset.wikiTarget);
630
647
  return;
631
648
  }
632
649
 
@@ -731,6 +748,7 @@ function handleConnectionChange(state) {
731
748
  });
732
749
  }
733
750
  this.renderPresence();
751
+ this.renderChat({ messagesChanged: false });
734
752
 
735
753
  if (state.unreachable && !this.connectionHelpShown) {
736
754
  this.connectionHelpShown = true;
@@ -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 {() => void} handleHashChange
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
  }
@@ -10,44 +10,23 @@ import {
10
10
  } from '../../../domain/file-kind.js';
11
11
 
12
12
  export const workspaceFeature = {
13
- isExcalidrawFile(filePath) {
14
- return isExcalidrawFilePath(filePath);
15
- },
16
-
17
- isBaseFile(filePath) {
18
- return isBaseFilePath(filePath);
19
- },
20
-
21
- isDrawioFile(filePath) {
22
- return isDrawioFilePath(filePath);
23
- },
24
-
25
- isImageFile(filePath) {
26
- return isImageAttachmentFilePath(filePath);
27
- },
28
-
29
- isMermaidFile(filePath) {
30
- return isMermaidFilePath(filePath);
31
- },
32
-
33
- isPlantUmlFile(filePath) {
34
- return isPlantUmlFilePath(filePath);
35
- },
36
-
37
- createDiagramPreviewDocument(language, source = '') {
38
- return this.workspacePreviewController.createDiagramPreviewDocument(language, source);
39
- },
13
+ isBaseFile: isBaseFilePath,
14
+ isDrawioFile: isDrawioFilePath,
15
+ isExcalidrawFile: isExcalidrawFilePath,
16
+ isImageFile: isImageAttachmentFilePath,
17
+ isMermaidFile: isMermaidFilePath,
18
+ isPlantUmlFile: isPlantUmlFilePath,
40
19
 
41
20
  getPreviewSource() {
42
21
  const previewDocument = this.getStaticPreviewDocument?.();
43
22
  const previewFilePath = previewDocument?.currentFilePath ?? previewDocument?.filePath ?? null;
44
23
  if (previewDocument && previewFilePath && previewFilePath === this.currentFilePath) {
45
24
  if (this.isMermaidFile(this.currentFilePath)) {
46
- return this.createDiagramPreviewDocument('mermaid', previewDocument.content);
25
+ return this.workspacePreviewController.createDiagramPreviewDocument('mermaid', previewDocument.content);
47
26
  }
48
27
 
49
28
  if (this.isPlantUmlFile(this.currentFilePath)) {
50
- return this.createDiagramPreviewDocument('plantuml', previewDocument.content);
29
+ return this.workspacePreviewController.createDiagramPreviewDocument('plantuml', previewDocument.content);
51
30
  }
52
31
 
53
32
  return String(previewDocument.content ?? '');
@@ -91,14 +70,6 @@ export const workspaceFeature = {
91
70
  .pop());
92
71
  },
93
72
 
94
- resetPreviewMode() {
95
- this.workspacePreviewController.resetPreviewMode();
96
- },
97
-
98
- syncFileChrome(filePath, options = {}) {
99
- this.workspacePreviewController.syncFileChrome(filePath, options);
100
- },
101
-
102
73
  handleLayoutViewRequest(view) {
103
74
  if (!this.currentFilePath || !this.isDrawioFile(this.currentFilePath)) {
104
75
  return true;
@@ -125,24 +96,22 @@ export const workspaceFeature = {
125
96
  return false;
126
97
  },
127
98
 
128
- renderExcalidrawFilePreview(filePath) {
129
- this.workspacePreviewController.renderExcalidrawFilePreview(filePath);
130
- },
131
-
132
- renderDrawioFilePreview(filePath) {
133
- this.workspacePreviewController.renderDrawioFilePreview(filePath);
99
+ renderBaseFilePreview(filePath, options) {
100
+ clearTimeout(this._basePreviewRenderTimer);
101
+ this._basePreviewRenderTimer = null;
102
+ return this.workspacePreviewController.renderBaseFilePreview(filePath, options);
134
103
  },
135
104
 
136
- renderImageFilePreview(filePath) {
137
- this.workspacePreviewController.renderImageFilePreview(filePath);
138
- },
139
-
140
- renderBaseFilePreview(filePath) {
141
- return this.workspacePreviewController.renderBaseFilePreview(filePath);
142
- },
143
-
144
- renderTextFilePreview(payload) {
145
- this.workspacePreviewController.renderTextFilePreview(payload);
105
+ scheduleBaseFilePreview(filePath, options) {
106
+ const loadToken = this.sessionLoadToken;
107
+ clearTimeout(this._basePreviewRenderTimer);
108
+ this._basePreviewRenderTimer = setTimeout(() => {
109
+ this._basePreviewRenderTimer = null;
110
+ if (filePath !== this.currentFilePath || loadToken !== this.sessionLoadToken) {
111
+ return;
112
+ }
113
+ void this.renderBaseFilePreview(filePath, options);
114
+ }, 180);
146
115
  },
147
116
 
148
117
  createResizeHandler() {
@@ -187,10 +156,6 @@ export const workspaceFeature = {
187
156
  });
188
157
  },
189
158
 
190
- async handleHashChange() {
191
- await this.workspaceRouteController.handleHashChange();
192
- },
193
-
194
159
  showEmptyState() {
195
160
  clearTimeout(this._previewLayoutSyncTimer);
196
161
  this._previewLayoutSyncTimer = null;
@@ -207,30 +172,4 @@ export const workspaceFeature = {
207
172
  this.workspaceRouteController.showDiffState();
208
173
  },
209
174
 
210
- async openFile(filePath) {
211
- await this.workspaceRouteController.openFile(filePath);
212
- },
213
-
214
- cleanupSession() {
215
- this.workspaceRouteController.cleanupSession();
216
- },
217
-
218
- handleWikiLinkClick(target) {
219
- this.wikiLinkFileController.handleWikiLinkClick(target);
220
- },
221
-
222
- normalizeNewWikiFilePath(target) {
223
- return this.wikiLinkFileController.normalizeNewWikiFilePath(target);
224
- },
225
-
226
- async createAndOpenFile(filePath, displayName) {
227
- await this.wikiLinkFileController.createAndOpenFile(filePath, displayName);
228
- },
229
-
230
- handleFileSelection(filePath, { closeSidebarOnMobile = false, revealInTree = false } = {}) {
231
- this.workspaceRouteController.handleFileSelection(filePath, {
232
- closeSidebarOnMobile,
233
- revealInTree,
234
- });
235
- },
236
175
  };
@@ -6,10 +6,13 @@ export function bindAppShellElements(doc = document) {
6
6
  chatForm: doc.getElementById('chatForm'),
7
7
  chatInput: doc.getElementById('chatInput'),
8
8
  chatMessages: doc.getElementById('chatMessages'),
9
- chatNotificationButton: doc.getElementById('chatNotificationBtn'),
10
9
  chatPanel: doc.getElementById('chatPanel'),
10
+ chatCloseButton: doc.getElementById('chatCloseBtn'),
11
11
  chatStatus: doc.getElementById('chatStatus'),
12
12
  chatToastContainer: doc.getElementById('chatToastContainer'),
13
+ chatNotificationButton: doc.getElementById('chatNotificationBtn'),
14
+ chatNotificationMuteButton: doc.getElementById('chatNotificationMuteBtn'),
15
+ chatNotificationStatus: doc.getElementById('chatNotificationStatus'),
13
16
  chatToggleBadge: doc.getElementById('chatToggleBadge'),
14
17
  chatToggleButton: doc.getElementById('chatToggleBtn'),
15
18
  gitCommitCancel: doc.getElementById('gitCommitCancel'),
@@ -57,6 +60,7 @@ export function bindAppShellElements(doc = document) {
57
60
  presencePanelList: doc.getElementById('presencePanelList'),
58
61
  presencePanelStatus: doc.getElementById('presencePanelStatus'),
59
62
  searchFilesButton: doc.getElementById('searchFilesBtn'),
63
+ toolbarSearchButton: doc.getElementById('toolbarSearchBtn'),
60
64
  shareButton: doc.getElementById('shareBtn'),
61
65
  toastContainer: doc.getElementById('toastContainer'),
62
66
  toggleWrapButton: doc.getElementById('toggleWrapBtn'),
@@ -68,6 +72,7 @@ export function bindAppShellElements(doc = document) {
68
72
  sidebarClose: doc.getElementById('sidebarClose'),
69
73
  sidebarBackdrop: doc.getElementById('sidebarBackdrop'),
70
74
  sidebar: doc.getElementById('sidebar'),
75
+ sidebarResizer: doc.getElementById('sidebarResizer'),
71
76
  emptyState: doc.getElementById('emptyState'),
72
77
  emptyStateNewFileBtn: doc.getElementById('emptyStateNewFileBtn'),
73
78
  emptyStateSearchBtn: doc.getElementById('emptyStateSearchBtn'),
@@ -90,6 +95,7 @@ export function bindAppShellElements(doc = document) {
90
95
  toolbarDiffBadge: doc.getElementById('toolbarDiffBadge'),
91
96
  toolbarOverflowMenu: doc.getElementById('toolbarOverflowMenu'),
92
97
  toolbarOverflowToggle: doc.getElementById('toolbarOverflowToggle'),
98
+ toolbarViewToggle: doc.getElementById('toolbarViewToggle'),
93
99
  sidebarTabs: doc.getElementById('sidebarTabs'),
94
100
  };
95
101
  }