vzcode 2.0.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 (218) 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-BgqNq-ww.js → index-DuUjtrt6.js} +107 -107
  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 +23 -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/MicSVG.tsx +0 -25
  79. package/src/client/Icons/NewSVG.tsx +0 -19
  80. package/src/client/Icons/PinSVG.tsx +0 -14
  81. package/src/client/Icons/PlaySVG.tsx +0 -16
  82. package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
  83. package/src/client/Icons/ReactSVG.tsx +0 -16
  84. package/src/client/Icons/SearchSVG.tsx +0 -20
  85. package/src/client/Icons/SparklesSVG.tsx +0 -23
  86. package/src/client/Icons/SplitEditorSVG.tsx +0 -34
  87. package/src/client/Icons/StopSVG.tsx +0 -15
  88. package/src/client/Icons/SvelteSVG.tsx +0 -16
  89. package/src/client/Icons/TrashSVG.tsx +0 -19
  90. package/src/client/Icons/TypeScriptSVG.tsx +0 -16
  91. package/src/client/Icons/index.tsx +0 -24
  92. package/src/client/ImageViewer/index.tsx +0 -91
  93. package/src/client/ImageViewer/style.scss +0 -41
  94. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
  95. package/src/client/PresenceNotifications/index.tsx +0 -158
  96. package/src/client/PresenceNotifications/style.scss +0 -17
  97. package/src/client/RunCodeWidget/index.tsx +0 -117
  98. package/src/client/RunCodeWidget/style.scss +0 -24
  99. package/src/client/SplitPaneResizeContext.tsx +0 -159
  100. package/src/client/TabList/Tab.tsx +0 -73
  101. package/src/client/TabList/index.tsx +0 -35
  102. package/src/client/TabList/style.scss +0 -51
  103. package/src/client/VZCodeContext/index.tsx +0 -29
  104. package/src/client/VZCodeContext/types.ts +0 -249
  105. package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
  106. package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
  107. package/src/client/VZLeft.tsx +0 -28
  108. package/src/client/VZMiddle.tsx +0 -172
  109. package/src/client/VZResizer/index.tsx +0 -128
  110. package/src/client/VZResizer/styles.scss +0 -33
  111. package/src/client/VZRight.tsx +0 -113
  112. package/src/client/VZSettings.tsx +0 -275
  113. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -196
  114. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
  115. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
  116. package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
  117. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
  118. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
  119. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
  120. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  121. package/src/client/VZSidebar/AIChat/index.tsx +0 -273
  122. package/src/client/VZSidebar/AIChat/styles.scss +0 -627
  123. package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
  124. package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
  125. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
  126. package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
  127. package/src/client/VZSidebar/EmptyState.tsx +0 -11
  128. package/src/client/VZSidebar/FileListing.tsx +0 -91
  129. package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
  130. package/src/client/VZSidebar/Item.tsx +0 -237
  131. package/src/client/VZSidebar/Listing.tsx +0 -47
  132. package/src/client/VZSidebar/Search.tsx +0 -527
  133. package/src/client/VZSidebar/VisualEditor.tsx +0 -295
  134. package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
  135. package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
  136. package/src/client/VZSidebar/index.tsx +0 -728
  137. package/src/client/VZSidebar/styles.scss +0 -612
  138. package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
  139. package/src/client/bootstrap.ts +0 -26
  140. package/src/client/buildWorker.ts +0 -3
  141. package/src/client/featureFlags.ts +0 -8
  142. package/src/client/generateRequestId.ts +0 -6
  143. package/src/client/getFileTree.ts +0 -53
  144. package/src/client/index.ts +0 -19
  145. package/src/client/main.jsx +0 -10
  146. package/src/client/presenceColor.ts +0 -8
  147. package/src/client/shouldTriggerRun.ts +0 -31
  148. package/src/client/sortFileTree.ts +0 -21
  149. package/src/client/tabsSearchParameters.test.ts +0 -79
  150. package/src/client/tabsSearchParameters.ts +0 -137
  151. package/src/client/themes/index.ts +0 -7
  152. package/src/client/themes/themes.ts +0 -77
  153. package/src/client/themes/uiwImports.ts +0 -32
  154. package/src/client/themes/useDynamicTheme.ts +0 -29
  155. package/src/client/themes/vizhubTheme/colors.ts +0 -80
  156. package/src/client/themes/vizhubTheme/index.ts +0 -193
  157. package/src/client/useActions.ts +0 -288
  158. package/src/client/useESLint/index.ts +0 -72
  159. package/src/client/useESLint/worker.ts +0 -113
  160. package/src/client/useEditorCache.ts +0 -35
  161. package/src/client/useFileCRUD.ts +0 -228
  162. package/src/client/useKeyboardShortcuts.ts +0 -451
  163. package/src/client/useOpenDirectories.ts +0 -99
  164. package/src/client/usePresenceAutoFollow.ts +0 -85
  165. package/src/client/usePrettier/index.ts +0 -178
  166. package/src/client/usePrettier/worker.ts +0 -109
  167. package/src/client/useRunCode.tsx +0 -15
  168. package/src/client/useRuntimeError.ts +0 -32
  169. package/src/client/useSubmitOperation.ts +0 -15
  170. package/src/client/useURLSync.ts +0 -137
  171. package/src/client/usernameLocalStorage.ts +0 -43
  172. package/src/client/utils/fileExtension.ts +0 -10
  173. package/src/client/utils/isImageFile.ts +0 -12
  174. package/src/client/vzReducer/aiChatReducer.ts +0 -44
  175. package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
  176. package/src/client/vzReducer/closeTabsReducer.ts +0 -96
  177. package/src/client/vzReducer/createInitialState.ts +0 -38
  178. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
  179. package/src/client/vzReducer/findPane.ts +0 -19
  180. package/src/client/vzReducer/index.ts +0 -250
  181. package/src/client/vzReducer/openTabReducer.test.ts +0 -127
  182. package/src/client/vzReducer/openTabReducer.ts +0 -74
  183. package/src/client/vzReducer/searchReducer.test.ts +0 -292
  184. package/src/client/vzReducer/searchReducer.ts +0 -181
  185. package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
  186. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
  187. package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
  188. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
  189. package/src/client/vzReducer/setThemeReducer.ts +0 -9
  190. package/src/client/vzReducer/setUsernameReducer.ts +0 -9
  191. package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
  192. package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
  193. package/src/client/vzReducer/updatePane.ts +0 -40
  194. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
  195. package/src/client/vzReducer/visualEditorReducer.ts +0 -9
  196. package/src/reactRouterExports.ts +0 -15
  197. package/src/runCode.ts +0 -27
  198. package/src/server/aiChatHandler/aiEditing.ts +0 -152
  199. package/src/server/aiChatHandler/chatOperations.ts +0 -510
  200. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  201. package/src/server/aiChatHandler/index.ts +0 -200
  202. package/src/server/aiChatHandler/llmStreaming.ts +0 -419
  203. package/src/server/aiChatHandler/undoHandler.ts +0 -97
  204. package/src/server/aiChatHandler/validation.ts +0 -24
  205. package/src/server/computeInitialDocument.ts +0 -220
  206. package/src/server/generateAIResponse.ts +0 -188
  207. package/src/server/handleAIAssist.ts +0 -53
  208. package/src/server/handleAIChatUndo.ts +0 -2
  209. package/src/server/handleAICopilot.ts +0 -97
  210. package/src/server/index.ts +0 -388
  211. package/src/server/livekit.ts +0 -24
  212. package/src/server/prettier.ts +0 -115
  213. package/src/submitOperation.ts +0 -25
  214. package/src/types.ts +0 -205
  215. package/src/utils/fileDiff.ts +0 -117
  216. package/src/vite-env.d.ts +0 -10
  217. /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
  218. /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
- };