vzcode 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/dist/assets/{buildWorker-Dsx6rOdK.js → buildWorker-wLkQ0yz1.js} +64 -64
  2. package/dist/assets/{index-BM8tDh6M.css → index-BoFeK4GL.css} +1 -1
  3. package/dist/assets/{index-CpxqGhXj.js → index-DuUjtrt6.js} +150 -150
  4. package/dist/assets/{worker-BeBZGG1n.js → worker-DHxSPM7N.js} +78 -78
  5. package/dist/cli.js +113 -0
  6. package/dist/index.html +2 -2
  7. package/{src/ot.ts → dist/ot.js} +2 -14
  8. package/{src/randomId.ts → dist/randomId.js} +5 -6
  9. package/dist/runCode.js +20 -0
  10. package/dist/server/aiChatHandler/aiEditing.js +89 -0
  11. package/dist/server/aiChatHandler/chatOperations.js +360 -0
  12. package/dist/server/aiChatHandler/errorHandling.js +49 -0
  13. package/dist/server/aiChatHandler/index.js +112 -0
  14. package/dist/server/aiChatHandler/llmStreaming.js +284 -0
  15. package/dist/server/aiChatHandler/validation.js +19 -0
  16. package/dist/server/computeInitialDocument.js +146 -0
  17. package/{src/server/config.ts → dist/server/config.js} +4 -7
  18. package/{src/server/featureFlags.ts → dist/server/featureFlags.js} +0 -3
  19. package/dist/server/generateAIResponse.js +129 -0
  20. package/dist/server/handleAIAssist.js +39 -0
  21. package/dist/server/handleAICopilot.js +81 -0
  22. package/dist/server/index.js +297 -0
  23. package/dist/server/livekit.js +17 -0
  24. package/dist/server/prettier.js +90 -0
  25. package/{src/server/setupEnv.ts → dist/server/setupEnv.js} +1 -2
  26. package/dist/submitOperation.js +14 -0
  27. package/dist/types.js +1 -0
  28. package/dist/utils/fileDiff.js +66 -0
  29. package/package.json +22 -22
  30. package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +0 -42
  31. package/src/client/AIAssist/AIAssistWidget/index.tsx +0 -135
  32. package/src/client/AIAssist/AIAssistWidget/style.scss +0 -47
  33. package/src/client/AIAssist/Spinner.jsx +0 -76
  34. package/src/client/AIAssist/formatFile.ts +0 -27
  35. package/src/client/AIAssist/generateFilesContext.ts +0 -25
  36. package/src/client/AIAssist/index.ts +0 -2
  37. package/src/client/AIAssist/startAIAssist.ts +0 -95
  38. package/src/client/App/index.tsx +0 -153
  39. package/src/client/App/style.scss +0 -82
  40. package/src/client/App/usePending.ts +0 -51
  41. package/src/client/App/useShareDB.ts +0 -161
  42. package/src/client/CodeEditor/Copilot/index.ts +0 -74
  43. package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +0 -12
  44. package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +0 -68
  45. package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +0 -174
  46. package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +0 -79
  47. package/src/client/CodeEditor/InteractiveWidgets/index.ts +0 -44
  48. package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +0 -12
  49. package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +0 -20
  50. package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +0 -143
  51. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +0 -48
  52. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +0 -12
  53. package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +0 -25
  54. package/src/client/CodeEditor/basicSetup.ts +0 -73
  55. package/src/client/CodeEditor/getOrCreateEditor.tsx +0 -615
  56. package/src/client/CodeEditor/index.tsx +0 -202
  57. package/src/client/CodeEditor/json1PresenceBroadcast.ts +0 -41
  58. package/src/client/CodeEditor/json1PresenceDisplay.ts +0 -350
  59. package/src/client/CodeEditor/rainbowBrackets.ts +0 -122
  60. package/src/client/CodeEditor/style.scss +0 -156
  61. package/src/client/CodeEditor/typescriptExtension/worker.ts +0 -32
  62. package/src/client/CodeErrorOverlay/index.tsx +0 -77
  63. package/src/client/CodeErrorOverlay/style.scss +0 -33
  64. package/src/client/Fonts/fonts.ts +0 -8
  65. package/src/client/Icons/AdjustmentSVG.tsx +0 -19
  66. package/src/client/Icons/BugSVG.tsx +0 -20
  67. package/src/client/Icons/CloseSVG.tsx +0 -19
  68. package/src/client/Icons/CssSVG.tsx +0 -16
  69. package/src/client/Icons/DirectoryArrowSVG.tsx +0 -19
  70. package/src/client/Icons/EditSVG.tsx +0 -19
  71. package/src/client/Icons/FileSVG.tsx +0 -19
  72. package/src/client/Icons/FolderSVG.tsx +0 -20
  73. package/src/client/Icons/GearSVG.tsx +0 -16
  74. package/src/client/Icons/HtmlSVG.tsx +0 -16
  75. package/src/client/Icons/JavaScriptSVG.tsx +0 -16
  76. package/src/client/Icons/JsonSVG.tsx +0 -16
  77. package/src/client/Icons/MarkdownSVG.tsx +0 -16
  78. package/src/client/Icons/MicOffSVG.tsx +0 -35
  79. package/src/client/Icons/MicSVG.tsx +0 -25
  80. package/src/client/Icons/NewSVG.tsx +0 -19
  81. package/src/client/Icons/PinSVG.tsx +0 -14
  82. package/src/client/Icons/PlaySVG.tsx +0 -16
  83. package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
  84. package/src/client/Icons/ReactSVG.tsx +0 -16
  85. package/src/client/Icons/SearchSVG.tsx +0 -20
  86. package/src/client/Icons/SparklesSVG.tsx +0 -23
  87. package/src/client/Icons/SplitEditorSVG.tsx +0 -34
  88. package/src/client/Icons/StopSVG.tsx +0 -15
  89. package/src/client/Icons/SvelteSVG.tsx +0 -16
  90. package/src/client/Icons/TrashSVG.tsx +0 -19
  91. package/src/client/Icons/TypeScriptSVG.tsx +0 -16
  92. package/src/client/Icons/index.tsx +0 -26
  93. package/src/client/ImageViewer/index.tsx +0 -91
  94. package/src/client/ImageViewer/style.scss +0 -41
  95. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
  96. package/src/client/PresenceNotifications/index.tsx +0 -158
  97. package/src/client/PresenceNotifications/style.scss +0 -17
  98. package/src/client/RunCodeWidget/index.tsx +0 -117
  99. package/src/client/RunCodeWidget/style.scss +0 -24
  100. package/src/client/SplitPaneResizeContext.tsx +0 -159
  101. package/src/client/TabList/Tab.tsx +0 -73
  102. package/src/client/TabList/index.tsx +0 -35
  103. package/src/client/TabList/style.scss +0 -51
  104. package/src/client/VZCodeContext/index.tsx +0 -29
  105. package/src/client/VZCodeContext/types.ts +0 -249
  106. package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
  107. package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
  108. package/src/client/VZLeft.tsx +0 -28
  109. package/src/client/VZMiddle.tsx +0 -172
  110. package/src/client/VZResizer/index.tsx +0 -128
  111. package/src/client/VZResizer/styles.scss +0 -33
  112. package/src/client/VZRight.tsx +0 -113
  113. package/src/client/VZSettings.tsx +0 -275
  114. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -239
  115. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
  116. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
  117. package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
  118. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
  119. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
  120. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
  121. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  122. package/src/client/VZSidebar/AIChat/index.tsx +0 -273
  123. package/src/client/VZSidebar/AIChat/styles.scss +0 -627
  124. package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +0 -117
  125. package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
  126. package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
  127. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
  128. package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
  129. package/src/client/VZSidebar/EmptyState.tsx +0 -11
  130. package/src/client/VZSidebar/FileListing.tsx +0 -91
  131. package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
  132. package/src/client/VZSidebar/Item.tsx +0 -237
  133. package/src/client/VZSidebar/Listing.tsx +0 -47
  134. package/src/client/VZSidebar/Search.tsx +0 -527
  135. package/src/client/VZSidebar/VisualEditor.tsx +0 -282
  136. package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
  137. package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
  138. package/src/client/VZSidebar/index.tsx +0 -728
  139. package/src/client/VZSidebar/styles.scss +0 -612
  140. package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
  141. package/src/client/bootstrap.ts +0 -26
  142. package/src/client/buildWorker.ts +0 -3
  143. package/src/client/featureFlags.ts +0 -8
  144. package/src/client/generateRequestId.ts +0 -6
  145. package/src/client/getFileTree.ts +0 -53
  146. package/src/client/index.ts +0 -19
  147. package/src/client/main.jsx +0 -10
  148. package/src/client/presenceColor.ts +0 -8
  149. package/src/client/shouldTriggerRun.ts +0 -31
  150. package/src/client/sortFileTree.ts +0 -21
  151. package/src/client/tabsSearchParameters.test.ts +0 -79
  152. package/src/client/tabsSearchParameters.ts +0 -137
  153. package/src/client/themes/index.ts +0 -7
  154. package/src/client/themes/themes.ts +0 -77
  155. package/src/client/themes/uiwImports.ts +0 -32
  156. package/src/client/themes/useDynamicTheme.ts +0 -29
  157. package/src/client/themes/vizhubTheme/colors.ts +0 -80
  158. package/src/client/themes/vizhubTheme/index.ts +0 -193
  159. package/src/client/useActions.ts +0 -288
  160. package/src/client/useESLint/index.ts +0 -72
  161. package/src/client/useESLint/worker.ts +0 -113
  162. package/src/client/useEditorCache.ts +0 -35
  163. package/src/client/useFileCRUD.ts +0 -228
  164. package/src/client/useKeyboardShortcuts.ts +0 -451
  165. package/src/client/useOpenDirectories.ts +0 -99
  166. package/src/client/usePresenceAutoFollow.ts +0 -85
  167. package/src/client/usePrettier/index.ts +0 -178
  168. package/src/client/usePrettier/worker.ts +0 -109
  169. package/src/client/useRunCode.tsx +0 -15
  170. package/src/client/useRuntimeError.ts +0 -32
  171. package/src/client/useSubmitOperation.ts +0 -15
  172. package/src/client/useURLSync.ts +0 -137
  173. package/src/client/usernameLocalStorage.ts +0 -43
  174. package/src/client/utils/fileExtension.ts +0 -10
  175. package/src/client/utils/isImageFile.ts +0 -12
  176. package/src/client/vzReducer/aiChatReducer.ts +0 -44
  177. package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
  178. package/src/client/vzReducer/closeTabsReducer.ts +0 -96
  179. package/src/client/vzReducer/createInitialState.ts +0 -38
  180. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
  181. package/src/client/vzReducer/findPane.ts +0 -19
  182. package/src/client/vzReducer/index.ts +0 -250
  183. package/src/client/vzReducer/openTabReducer.test.ts +0 -127
  184. package/src/client/vzReducer/openTabReducer.ts +0 -74
  185. package/src/client/vzReducer/searchReducer.test.ts +0 -292
  186. package/src/client/vzReducer/searchReducer.ts +0 -181
  187. package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
  188. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
  189. package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
  190. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
  191. package/src/client/vzReducer/setThemeReducer.ts +0 -9
  192. package/src/client/vzReducer/setUsernameReducer.ts +0 -9
  193. package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
  194. package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
  195. package/src/client/vzReducer/updatePane.ts +0 -40
  196. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
  197. package/src/client/vzReducer/visualEditorReducer.ts +0 -9
  198. package/src/reactRouterExports.ts +0 -15
  199. package/src/runCode.ts +0 -27
  200. package/src/server/aiChatHandler/aiEditing.ts +0 -152
  201. package/src/server/aiChatHandler/chatOperations.ts +0 -510
  202. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  203. package/src/server/aiChatHandler/index.ts +0 -200
  204. package/src/server/aiChatHandler/llmStreaming.ts +0 -419
  205. package/src/server/aiChatHandler/undoHandler.ts +0 -97
  206. package/src/server/aiChatHandler/validation.ts +0 -24
  207. package/src/server/computeInitialDocument.ts +0 -220
  208. package/src/server/generateAIResponse.ts +0 -188
  209. package/src/server/handleAIAssist.ts +0 -53
  210. package/src/server/handleAIChatUndo.ts +0 -2
  211. package/src/server/handleAICopilot.ts +0 -97
  212. package/src/server/index.ts +0 -388
  213. package/src/server/livekit.ts +0 -24
  214. package/src/server/prettier.ts +0 -115
  215. package/src/submitOperation.ts +0 -25
  216. package/src/types.ts +0 -205
  217. package/src/utils/fileDiff.ts +0 -117
  218. package/src/vite-env.d.ts +0 -10
  219. /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
  220. /package/{src/server/isDirectory.ts → dist/server/isDirectory.js} +0 -0
@@ -1,728 +0,0 @@
1
- import {
2
- useCallback,
3
- useContext,
4
- useEffect,
5
- useMemo,
6
- useState,
7
- useRef,
8
- } from 'react';
9
- import {
10
- FileTree,
11
- FileTreeFile,
12
- Presence,
13
- PresenceId,
14
- PresenceIndicator,
15
- } from '../../types';
16
- import { VizFileId } from '@vizhub/viz-types';
17
- import { OverlayTrigger, Tooltip } from '../bootstrap';
18
- import { getFileTree } from '../getFileTree';
19
- import {
20
- BugSVG,
21
- FileSVG,
22
- FolderSVG,
23
- GearSVG,
24
- NewSVG,
25
- PinSVG,
26
- QuestionMarkSVG,
27
- SearchSVG,
28
- SparklesSVG,
29
- AdjustmentSVG,
30
- } from '../Icons';
31
- import { MicSVG } from '../Icons/MicSVG';
32
- import { sortFileTree } from '../sortFileTree';
33
- import { SplitPaneResizeContext } from '../SplitPaneResizeContext';
34
- import { VZCodeContext } from '../VZCodeContext';
35
- import { AIChat } from './AIChat';
36
- import { Listing } from './Listing';
37
- import { Search } from './Search';
38
- import { DeleteConfirmationModal } from './DeleteConfirmationModal';
39
- import { useDragAndDrop } from './useDragAndDrop';
40
- import { createAICopyPasteHandlers } from './aiCopyPaste';
41
- import {
42
- enableLiveKit,
43
- enableAIChat,
44
- } from '../featureFlags';
45
- import './styles.scss';
46
- import { VisualEditor } from './VisualEditor';
47
-
48
- const enableConnectionStatus = true;
49
-
50
- export const VZSidebar = ({
51
- createFileTooltipText = (
52
- <>
53
- <strong>New file</strong>
54
- {/* TODO verify that Ctrl + Shift + N works - does not work in Linux */}
55
- <div>(Alt + N or Ctrl + Shift + N)</div>
56
- </>
57
- ),
58
- createDirTooltipText = (
59
- <div>
60
- <strong>New Directory</strong>
61
- {/* TODO consider Alt+D, as Ctrl + Shift + D does not work in Linux */}
62
- <div>(Ctrl + Shift + D)</div>
63
- </div>
64
- ),
65
- openSettingsTooltipText = (
66
- <div>
67
- <strong>Open Settings</strong>
68
- <div>(Ctrl + Shift + S or Ctrl + ,)</div>
69
- </div>
70
- ),
71
- openKeyboardShortcuts = (
72
- <div>
73
- <strong>Keyboard Shortcuts</strong>
74
- <div>(Ctrl + Shift + K)</div>
75
- </div>
76
- ),
77
- reportBugTooltipText = (
78
- <div>
79
- <strong>Report Bug</strong>
80
- {/* TODO get this keyboard shortcut working? */}
81
- {/* <div>(Ctrl + Shift + B)</div> */}
82
- </div>
83
- ),
84
- searchToolTipText = (
85
- <div>
86
- <strong>Search</strong>
87
- <div>(Ctrl + Shift + F)</div>
88
- </div>
89
- ),
90
- filesToolTipText = (
91
- <div>
92
- <strong>Files</strong>
93
- <div>(Ctrl + Shift + E)</div>
94
- </div>
95
- ),
96
- enableAutoFollowTooltipText = (
97
- <div>
98
- <strong>Enable Auto Follow</strong>
99
- <div>(Ctrl + Shift + A)</div>
100
- </div>
101
- ),
102
- disableAutoFollowTooltipText = (
103
- <div>
104
- <strong>Disable Auto Follow</strong>
105
- {/* TODO consider Alt+A, this breaks in Linux */}
106
- <div>(Ctrl + Shift + A)</div>
107
- </div>
108
- ),
109
- voiceChatToolTipText = (
110
- <div>
111
- <strong>Open Voice Chat Menu</strong>
112
- </div>
113
- ),
114
- aiChatToolTipText = (
115
- <div>
116
- <strong>Edit with AI</strong>
117
- </div>
118
- ),
119
-
120
- visualEditorToolTipText = (
121
- <div>
122
- <strong>Visual Editor</strong>
123
- </div>
124
- ),
125
- }: {
126
- createFileTooltipText?: React.ReactNode;
127
- createDirTooltipText?: React.ReactNode;
128
- openSettingsTooltipText?: React.ReactNode;
129
- reportBugTooltipText?: React.ReactNode;
130
- openKeyboardShortcuts?: React.ReactNode;
131
- searchToolTipText?: React.ReactNode;
132
- filesToolTipText?: React.ReactNode;
133
- enableAutoFollowTooltipText?: React.ReactNode;
134
- disableAutoFollowTooltipText?: React.ReactNode;
135
- voiceChatToolTipText?: React.ReactNode;
136
- aiChatToolTipText?: React.ReactNode;
137
- visualEditorToolTipText?: React.ReactNode;
138
- }) => {
139
- const {
140
- files,
141
- openTab,
142
- setIsSettingsOpen,
143
- setIsDocOpen,
144
- isSearchOpen,
145
- setIsSearchOpen,
146
- isVisualEditorOpen,
147
- setIsVisualEditorOpen,
148
- isAIChatOpen,
149
- setIsAIChatOpen,
150
- handleOpenCreateFileModal,
151
- handleOpenCreateDirModal,
152
- connected,
153
- pending,
154
- sidebarRef,
155
- enableAutoFollow,
156
- toggleAutoFollow,
157
- docPresence,
158
- updatePresenceIndicator,
159
- setVoiceChatModalOpen,
160
- submitOperation,
161
- deleteAllFiles,
162
- } = useContext(VZCodeContext);
163
-
164
- const fileTree = useMemo(
165
- () => (files ? sortFileTree(getFileTree(files)) : null),
166
- [files],
167
- );
168
- const handleQuestionMarkClick = useCallback(() => {
169
- setIsDocOpen(true);
170
- }, []);
171
- const handleSettingsClick = useCallback(() => {
172
- setIsSettingsOpen(true);
173
- }, []);
174
-
175
- // State for AI operation feedback
176
- const [copyButtonText, setCopyButtonText] =
177
- useState('Copy for AI');
178
- const [pasteButtonText, setPasteButtonText] =
179
- useState('Paste for AI');
180
- const [exportButtonText, setExportButtonText] =
181
- useState('Export to ZIP');
182
-
183
- // State for delete all confirmation modal
184
- const [showDeleteAllModal, setShowDeleteAllModal] =
185
- useState(false);
186
-
187
- // Create AI copy/paste handlers
188
- const {
189
- handleCopyForAI,
190
- handlePasteForAI,
191
- handleExportToZip,
192
- } = useMemo(
193
- () =>
194
- createAICopyPasteHandlers(
195
- files,
196
- submitOperation,
197
- setCopyButtonText,
198
- setPasteButtonText,
199
- setExportButtonText,
200
- ),
201
- [files, submitOperation],
202
- );
203
-
204
- // Delete all handlers
205
- const handleDeleteAllClick = useCallback(() => {
206
- setShowDeleteAllModal(true);
207
- }, []);
208
-
209
- const handleDeleteAllModalClose = useCallback(() => {
210
- setShowDeleteAllModal(false);
211
- }, []);
212
-
213
- const handleDeleteAllConfirm = useCallback(() => {
214
- setShowDeleteAllModal(false);
215
- deleteAllFiles();
216
- }, [deleteAllFiles]);
217
-
218
- const { sidebarWidth, setSidebarView } = useContext(
219
- SplitPaneResizeContext,
220
- );
221
-
222
- // On single-click, open the file in a transient tab.
223
- const handleFileClick = useCallback(
224
- (fileId: VizFileId) => {
225
- openTab({ fileId, isTransient: true });
226
- },
227
- [openTab],
228
- );
229
-
230
- // On double-click, open the file in a persistent tab.
231
- const handleFileDoubleClick = useCallback(
232
- (fileId: VizFileId) => {
233
- openTab({ fileId, isTransient: false });
234
- },
235
- [openTab],
236
- );
237
-
238
- // True if files exist.
239
- const filesExist =
240
- fileTree &&
241
- fileTree.children &&
242
- fileTree.children.length > 0;
243
-
244
- const {
245
- isDragOver,
246
- handleDragEnter,
247
- handleDragOver,
248
- handleDragLeave,
249
- handleDrop,
250
- } = useDragAndDrop();
251
-
252
- // Track presence of remote users across files
253
- // so that they can be displayed in the sidebar.
254
- useEffect(() => {
255
- docPresence;
256
- }, []);
257
-
258
- // Track the presence indicators for display in sidebar
259
- useEffect(() => {
260
- if (docPresence) {
261
- const handleReceive = (
262
- presenceId: PresenceId,
263
- update: Presence,
264
- ) => {
265
- // Sometimes this can be null, so we check.
266
- // This can happen when the user disconnects.
267
- // If this happens, we do not update the presence indicator.
268
- // TODO test removal of presence indicator.
269
- if (!update) return;
270
-
271
- const presenceIndicator: PresenceIndicator = {
272
- username: update.username,
273
- fileId: update.start[1] as VizFileId,
274
- };
275
-
276
- updatePresenceIndicator(presenceIndicator);
277
- };
278
-
279
- docPresence.on('receive', handleReceive);
280
- return () => {
281
- docPresence.off('receive', handleReceive);
282
- };
283
- }
284
- }, [docPresence]);
285
-
286
- const [saved, setSaved] = useState(false);
287
- const [isConnecting, setIsConnecting] = useState(true);
288
- const previousPendingRef = useRef<boolean>(pending);
289
-
290
- // Handle connection status transitions
291
- useEffect(() => {
292
- if (isConnecting && connected) {
293
- setIsConnecting(false);
294
- }
295
- }, [connected, isConnecting]);
296
-
297
- // Handle 'saved' state based on 'pending' transition
298
- useEffect(() => {
299
- // Check if 'pending' transitioned from true to false
300
- if (
301
- previousPendingRef.current &&
302
- !pending &&
303
- connected &&
304
- !isConnecting
305
- ) {
306
- setSaved(true);
307
- const timer = setTimeout(() => {
308
- setSaved(false);
309
- }, 1500); // Reset after 2 seconds
310
- return () => clearTimeout(timer);
311
- }
312
- // Update the ref with the current 'pending' state
313
- previousPendingRef.current = pending;
314
- }, [pending, connected, isConnecting]);
315
-
316
- // Automatically adjust sidebar width when view changes
317
- useEffect(() => {
318
- setSidebarView(isAIChatOpen);
319
- }, [isAIChatOpen, setSidebarView]);
320
-
321
- return (
322
- <div
323
- className="vz-sidebar"
324
- style={{ width: sidebarWidth + 'px' }}
325
- >
326
- <div
327
- className="full-box"
328
- ref={sidebarRef}
329
- tabIndex={-1}
330
- >
331
- <div className="sidebar-section-buttons">
332
- {enableAIChat && (
333
- <OverlayTrigger
334
- placement="right"
335
- overlay={
336
- <Tooltip id="ai-chat-tooltip">
337
- {aiChatToolTipText}
338
- </Tooltip>
339
- }
340
- >
341
- <i
342
- id="ai-chat-icon"
343
- className="icon-button icon-button-dark"
344
- onClick={() => {
345
- setIsAIChatOpen(true);
346
- setIsSearchOpen(false);
347
- setSidebarView(true); // Switch to AI chat view
348
- }}
349
- >
350
- <SparklesSVG />
351
- </i>
352
- </OverlayTrigger>
353
- )}
354
-
355
- <OverlayTrigger
356
- placement="right"
357
- overlay={
358
- <Tooltip id="files-tooltip">
359
- {filesToolTipText}
360
- </Tooltip>
361
- }
362
- >
363
- <i
364
- id="files-icon"
365
- className="icon-button icon-button-dark"
366
- onClick={() => {
367
- setIsSearchOpen(false);
368
- setIsAIChatOpen(false);
369
- setIsVisualEditorOpen(false);
370
- setSidebarView(false); // Switch to files view
371
- }}
372
- >
373
- <FolderSVG />
374
- </i>
375
- </OverlayTrigger>
376
-
377
- <OverlayTrigger
378
- placement="right"
379
- overlay={
380
- <Tooltip id="search-tooltip">
381
- {searchToolTipText}
382
- </Tooltip>
383
- }
384
- >
385
- <i
386
- id="search-icon"
387
- className="icon-button icon-button-dark"
388
- onClick={() => {
389
- setIsSearchOpen(true);
390
- setIsAIChatOpen(false);
391
- setIsVisualEditorOpen(false);
392
- setSidebarView(false); // Switch to files view (search uses same width as files)
393
- }}
394
- >
395
- <SearchSVG />
396
- </i>
397
- </OverlayTrigger>
398
-
399
- {enableAIChat && (
400
- <OverlayTrigger
401
- placement="right"
402
- overlay={
403
- <Tooltip id="ai-chat-tooltip">
404
- {aiChatToolTipText}
405
- </Tooltip>
406
- }
407
- >
408
- <i
409
- id="ai-chat-icon"
410
- className="icon-button icon-button-dark"
411
- onClick={() => {
412
- setIsAIChatOpen(true);
413
- setIsSearchOpen(false);
414
- setIsVisualEditorOpen(false);
415
- }}
416
- >
417
- <SparklesSVG />
418
- </i>
419
- </OverlayTrigger>
420
- )}
421
-
422
- <OverlayTrigger
423
- placement="right"
424
- overlay={
425
- <Tooltip id="visual-editor-tooltip">
426
- {visualEditorToolTipText}
427
- </Tooltip>
428
- }
429
- >
430
- <i
431
- id="visual-editor-icon"
432
- className="icon-button icon-button-dark"
433
- onClick={() => {
434
- setIsVisualEditorOpen(true);
435
- setIsAIChatOpen(false);
436
- setIsSearchOpen(false);
437
- }}
438
- >
439
- <AdjustmentSVG />
440
- </i>
441
- </OverlayTrigger>
442
-
443
- <OverlayTrigger
444
- placement="right"
445
- overlay={
446
- <Tooltip id="open-keyboard-shortcuts">
447
- {openKeyboardShortcuts}
448
- </Tooltip>
449
- }
450
- >
451
- <i
452
- id="shortcut-icon"
453
- className="icon-button icon-button-dark"
454
- onClick={handleQuestionMarkClick}
455
- >
456
- <QuestionMarkSVG />
457
- </i>
458
- </OverlayTrigger>
459
-
460
- <OverlayTrigger
461
- placement="right"
462
- overlay={
463
- <Tooltip id="report-bug-tooltip">
464
- {reportBugTooltipText}
465
- </Tooltip>
466
- }
467
- >
468
- <a
469
- href="https://github.com/vizhub-core/vzcode/issues/new"
470
- target="_blank"
471
- rel="noopener noreferrer"
472
- >
473
- <i
474
- id="bug-icon"
475
- className="icon-button icon-button-dark"
476
- >
477
- <BugSVG />
478
- </i>
479
- </a>
480
- </OverlayTrigger>
481
-
482
- <OverlayTrigger
483
- placement="right"
484
- overlay={
485
- <Tooltip id="open-settings-tooltip">
486
- {openSettingsTooltipText}
487
- </Tooltip>
488
- }
489
- >
490
- <i
491
- id="settings-icon"
492
- className="icon-button icon-button-dark"
493
- onClick={handleSettingsClick}
494
- >
495
- <GearSVG />
496
- </i>
497
- </OverlayTrigger>
498
-
499
- <OverlayTrigger
500
- placement="right"
501
- overlay={
502
- <Tooltip id="create-file-tooltip">
503
- {createFileTooltipText}
504
- </Tooltip>
505
- }
506
- >
507
- <i
508
- id="new-file-icon"
509
- className="icon-button icon-button-dark"
510
- onClick={handleOpenCreateFileModal}
511
- >
512
- <NewSVG />
513
- </i>
514
- </OverlayTrigger>
515
-
516
- {/*Directory Rename*/}
517
- <OverlayTrigger
518
- placement="right"
519
- overlay={
520
- <Tooltip id="create-dir-tooltip">
521
- {createDirTooltipText}
522
- </Tooltip>
523
- }
524
- >
525
- <i
526
- id="new-directory-icon"
527
- className="icon-button icon-button-dark"
528
- onClick={handleOpenCreateDirModal}
529
- >
530
- <FileSVG />
531
- </i>
532
- </OverlayTrigger>
533
-
534
- {/*Toggle Follow*/}
535
- <OverlayTrigger
536
- placement="right"
537
- overlay={
538
- <Tooltip id="toggle-auto-follow">
539
- {enableAutoFollow
540
- ? disableAutoFollowTooltipText
541
- : enableAutoFollowTooltipText}
542
- </Tooltip>
543
- }
544
- >
545
- <i
546
- id="auto-focus-icon"
547
- className={`icon-button icon-button-dark${
548
- enableAutoFollow
549
- ? ' vh-color-success-01'
550
- : ''
551
- }`}
552
- onClick={toggleAutoFollow}
553
- >
554
- <i></i>
555
- <PinSVG />
556
- </i>
557
- </OverlayTrigger>
558
- {/* Start Voice Chat */}
559
- {enableLiveKit && (
560
- <OverlayTrigger
561
- placement="right"
562
- overlay={
563
- <Tooltip id="voice-chat">
564
- {voiceChatToolTipText}
565
- </Tooltip>
566
- }
567
- >
568
- <i
569
- id="mic-icon"
570
- className="icon-button icon-button-dark"
571
- onClick={() => {
572
- setVoiceChatModalOpen(true);
573
- }}
574
- >
575
- <MicSVG />
576
- </i>
577
- </OverlayTrigger>
578
- )}
579
- </div>
580
- <div
581
- className="files"
582
- id="sidebar-view-container"
583
- onDragEnter={handleDragEnter}
584
- onDragOver={handleDragOver}
585
- onDragLeave={handleDragLeave}
586
- onDrop={handleDrop}
587
- >
588
- {isAIChatOpen ? (
589
- <div className="sidebar-ai-chat">
590
- <AIChat />
591
- </div>
592
- ) : isSearchOpen ? (
593
- <div className="sidebar-search">
594
- <Search />
595
- </div>
596
- ) : isVisualEditorOpen ? (
597
- <div className="sidebar-visual-editor">
598
- <VisualEditor />
599
- </div>
600
- ) : (
601
- <div className="sidebar-files">
602
- {isDragOver ? (
603
- <div className="empty drag-over">
604
- <div className="empty-text">
605
- It looks like you don't have any files
606
- yet! Click the "Create file" button
607
- above to create your first file.
608
- </div>
609
- <div className="empty-text">
610
- Drop files here!
611
- </div>
612
- </div>
613
- ) : filesExist ? (
614
- fileTree.children.map((entity) => {
615
- const { fileId } = entity as FileTreeFile;
616
- const { path } = entity as FileTree;
617
- const key = fileId ? fileId : path;
618
- return (
619
- <Listing
620
- key={key}
621
- entity={entity}
622
- handleFileClick={handleFileClick}
623
- handleFileDoubleClick={
624
- handleFileDoubleClick
625
- }
626
- />
627
- );
628
- })
629
- ) : (
630
- <div className="empty">
631
- <div className="empty-text">
632
- It looks like you don't have any files
633
- yet! Click the "Create file" button
634
- above to create your first file.
635
- </div>
636
- <div className="empty-text">
637
- Drop files here!
638
- </div>
639
- </div>
640
- )}
641
- </div>
642
- )}
643
- </div>
644
- </div>
645
- {!isAIChatOpen && !isSearchOpen && (
646
- <div className="ai-buttons">
647
- {filesExist && (
648
- <button
649
- className="ai-button export-button"
650
- onClick={handleExportToZip}
651
- title="Export files to ZIP"
652
- >
653
- <i className="bi bi-download"></i>
654
- {exportButtonText}
655
- </button>
656
- )}
657
- {filesExist && (
658
- <button
659
- className="ai-button copy-button"
660
- onClick={handleCopyForAI}
661
- title="Copy files formatted for AI"
662
- >
663
- <i className="bi bi-clipboard"></i>
664
- {copyButtonText}
665
- </button>
666
- )}
667
-
668
- <button
669
- className="ai-button paste-button"
670
- onClick={handlePasteForAI}
671
- title="Paste files from AI"
672
- >
673
- <i className="bi bi-clipboard-plus"></i>
674
- {pasteButtonText}
675
- </button>
676
-
677
- {filesExist && (
678
- <button
679
- className="ai-button delete-all-button"
680
- onClick={handleDeleteAllClick}
681
- title="Delete all files"
682
- >
683
- <i className="bi bi-trash"></i>
684
- delete all
685
- </button>
686
- )}
687
- </div>
688
- )}
689
- {enableConnectionStatus && (
690
- <div className="connection-status">
691
- {isConnecting
692
- ? 'Connecting...'
693
- : !connected
694
- ? 'Connection Lost'
695
- : pending
696
- ? 'Saving...'
697
- : saved
698
- ? 'Saved.'
699
- : 'Connected'}
700
- <div className="connection">
701
- <div
702
- className={`connection-status-indicator ${
703
- isConnecting
704
- ? 'pending'
705
- : !connected
706
- ? 'disconnected'
707
- : pending
708
- ? 'pending'
709
- : 'connected'
710
- }`}
711
- />
712
- </div>
713
- </div>
714
- )}
715
-
716
- {/* Delete All Files Confirmation Modal */}
717
- {showDeleteAllModal && (
718
- <DeleteConfirmationModal
719
- show={showDeleteAllModal}
720
- onClose={handleDeleteAllModalClose}
721
- onConfirm={handleDeleteAllConfirm}
722
- isDirectory={false}
723
- name="all files"
724
- />
725
- )}
726
- </div>
727
- );
728
- };