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,295 +0,0 @@
1
- import {
2
- useCallback,
3
- useContext,
4
- useState,
5
- useRef,
6
- useEffect,
7
- } from 'react';
8
- import { VZCodeContext } from '../VZCodeContext';
9
- import { VizContent, VizFileId } from '@vizhub/viz-types';
10
- import { VisualEditorConfigEntry } from '../../types';
11
- import { EmptyState } from './EmptyState';
12
-
13
- const CONFIG_FILE_NAME = 'config.json';
14
-
15
- export const VisualEditor = () => {
16
- const {
17
- files,
18
- submitOperation,
19
- runPrettierRef,
20
- iframeRef,
21
- } = useContext(VZCodeContext);
22
-
23
- let configFileId: VizFileId | null = null;
24
- for (const fileId in files) {
25
- if (files[fileId].name === CONFIG_FILE_NAME) {
26
- configFileId = fileId;
27
- break;
28
- }
29
- }
30
-
31
- if (configFileId === null) {
32
- return (
33
- <EmptyState>
34
- To begin using the visual editor, create a
35
- config.json.
36
- </EmptyState>
37
- );
38
- }
39
-
40
- let configData;
41
-
42
- try {
43
- configData = JSON.parse(files[configFileId].text);
44
- } catch (error) {
45
- return (
46
- <EmptyState>
47
- Your config.json file is not valid json.
48
- </EmptyState>
49
- );
50
- }
51
-
52
- if (!('visualEditorWidgets' in configData)) {
53
- return (
54
- <EmptyState>
55
- To begin using the visual editor, make sure your
56
- config.json has a key called "visualEditorWidgets",
57
- whose value is the config for the visual editor.
58
- </EmptyState>
59
- );
60
- }
61
-
62
- if (!Array.isArray(configData.visualEditorWidgets)) {
63
- return (
64
- <EmptyState>
65
- Your config.json file has "visualEditorWidgets" but
66
- it is not an array. Please make sure
67
- "visualEditorWidgets" is an array of widget
68
- configurations.
69
- </EmptyState>
70
- );
71
- }
72
-
73
- const onInputUpdate = useCallback(
74
- (
75
- property: string,
76
- previousValue: any,
77
- ): React.FormEventHandler<HTMLInputElement> =>
78
- (event) => {
79
- //TODO: test race condition in which someone is editing the config file as another user uses the visual editor
80
-
81
- const newValueOfConsistentType =
82
- typeof previousValue === 'number'
83
- ? parseFloat(event.currentTarget.value)
84
- : event.currentTarget.value;
85
-
86
- const newConfigData = {
87
- ...configData,
88
- [property]: newValueOfConsistentType,
89
- };
90
-
91
- submitOperation((document: VizContent) => ({
92
- ...document,
93
- files: {
94
- ...files,
95
- [configFileId]: {
96
- name: 'config.json',
97
- text: JSON.stringify(newConfigData, null, 2),
98
- },
99
- },
100
- }));
101
-
102
- iframeRef.current.contentWindow.postMessage({
103
- [property]: newValueOfConsistentType,
104
- });
105
- },
106
- [configData, files, configFileId],
107
- );
108
-
109
- const visualEditorWidgets: VisualEditorConfigEntry[] =
110
- configData.visualEditorWidgets;
111
-
112
- // State for advanced interactions
113
- const [activeSlider, setActiveSlider] = useState<
114
- string | null
115
- >(null);
116
- const [isDragging, setIsDragging] = useState<
117
- string | null
118
- >(null);
119
- const [hoverValue, setHoverValue] = useState<
120
- number | null
121
- >(null);
122
- const sliderRefs = useRef<{
123
- [key: string]: HTMLInputElement | null;
124
- }>({});
125
-
126
- // Helper function to format values nicely
127
- const formatValue = (
128
- value: number,
129
- min: number,
130
- max: number,
131
- ) => {
132
- // Determine decimal places based on the range
133
- const range = max - min;
134
- const decimalPlaces =
135
- range < 10 ? 2 : range < 100 ? 1 : 0;
136
- return Number(value).toFixed(decimalPlaces);
137
- };
138
-
139
- // Helper function to calculate percentage for progress fill
140
- const calculatePercentage = (
141
- value: number,
142
- min: number,
143
- max: number,
144
- ) => {
145
- return ((value - min) / (max - min)) * 100;
146
- };
147
-
148
- // Enhanced input handler with animations
149
- const onInputUpdateEnhanced = useCallback(
150
- (
151
- property: string,
152
- previousValue: any,
153
- widgetConfig: VisualEditorConfigEntry,
154
- ): React.FormEventHandler<HTMLInputElement> =>
155
- (event) => {
156
- const newValueOfConsistentType =
157
- typeof previousValue === 'number'
158
- ? parseFloat(event.currentTarget.value)
159
- : event.currentTarget.value;
160
-
161
- const newConfigData = {
162
- ...configData,
163
- [property]: newValueOfConsistentType,
164
- };
165
-
166
- submitOperation((document: VizContent) => ({
167
- ...document,
168
- files: {
169
- ...files,
170
- [configFileId]: {
171
- name: 'config.json',
172
- text: JSON.stringify(newConfigData, null, 2),
173
- },
174
- },
175
- }));
176
-
177
- iframeRef.current.contentWindow.postMessage({
178
- [property]: newValueOfConsistentType,
179
- });
180
-
181
- // Trigger value change animation
182
- const sliderElement = sliderRefs.current[property];
183
- if (sliderElement) {
184
- sliderElement.classList.add('value-changed');
185
- setTimeout(() => {
186
- sliderElement.classList.remove('value-changed');
187
- }, 300);
188
- }
189
- },
190
- [configData, files, configFileId],
191
- );
192
-
193
- // Mouse event handlers for enhanced interactions
194
- const handleMouseDown = (property: string) => {
195
- setIsDragging(property);
196
- setActiveSlider(property);
197
- };
198
-
199
- const handleMouseUp = () => {
200
- setIsDragging(null);
201
- };
202
-
203
- const handleMouseEnter = (property: string) => {
204
- setActiveSlider(property);
205
- };
206
-
207
- const handleMouseLeave = () => {
208
- setActiveSlider(null);
209
- setHoverValue(null);
210
- };
211
-
212
- // Add global mouse up listener
213
- useEffect(() => {
214
- const handleGlobalMouseUp = () => {
215
- setIsDragging(null);
216
- };
217
-
218
- document.addEventListener(
219
- 'mouseup',
220
- handleGlobalMouseUp,
221
- );
222
- return () => {
223
- document.removeEventListener(
224
- 'mouseup',
225
- handleGlobalMouseUp,
226
- );
227
- };
228
- }, []);
229
-
230
- return (
231
- <div className="visual-editor">
232
- {visualEditorWidgets.map((widgetConfig, index) => {
233
- if (widgetConfig.type === 'number') {
234
- const currentValue =
235
- configData[widgetConfig.property];
236
- const percentage = calculatePercentage(
237
- currentValue,
238
- widgetConfig.min,
239
- widgetConfig.max,
240
- );
241
-
242
- return (
243
- <div
244
- key={widgetConfig.property}
245
- className="visual-editor-slider"
246
- >
247
- <div className="slider-header">
248
- <label
249
- htmlFor={widgetConfig.property}
250
- className="slider-label"
251
- >
252
- {widgetConfig.label}
253
- </label>
254
- <span className="slider-value">
255
- {formatValue(
256
- currentValue,
257
- widgetConfig.min,
258
- widgetConfig.max,
259
- )}
260
- </span>
261
- </div>
262
- <div className="slider-container">
263
- <input
264
- type="range"
265
- id={widgetConfig.property}
266
- className="slider-input"
267
- min={widgetConfig.min}
268
- max={widgetConfig.max}
269
- step="any"
270
- onInput={onInputUpdate(
271
- widgetConfig.property,
272
- configData[widgetConfig.property],
273
- )}
274
- defaultValue={currentValue}
275
- />
276
- <div
277
- className="slider-track-fill"
278
- style={{ width: `${percentage}%` }}
279
- />
280
- </div>
281
- <div className="slider-bounds">
282
- <span className="min-value">
283
- {widgetConfig.min}
284
- </span>
285
- <span className="max-value">
286
- {widgetConfig.max}
287
- </span>
288
- </div>
289
- </div>
290
- );
291
- }
292
- })}
293
- </div>
294
- );
295
- };
@@ -1,121 +0,0 @@
1
- import {
2
- ParticipantLoop,
3
- ParticipantName,
4
- useParticipants,
5
- useRoomContext,
6
- } from '@livekit/components-react';
7
- import { useContext, useState } from 'react';
8
- import { Button, Form, Modal } from 'react-bootstrap';
9
- import { v4 } from 'uuid';
10
- import { VZCodeContext } from '../VZCodeContext';
11
-
12
- export function VoiceChatModal() {
13
- const {
14
- liveKitRoomName,
15
- setLiveKitRoom,
16
- liveKitToken,
17
- setLiveKitToken,
18
- liveKitConnection,
19
- setLiveKitConnection,
20
- voiceChatModalOpen,
21
- setVoiceChatModalOpen,
22
- } = useContext(VZCodeContext);
23
- const participants = useParticipants();
24
-
25
- const [roomName, setRoomName] = useState(
26
- liveKitRoomName || '',
27
- );
28
- const [username, setUsername] = useState('');
29
- const room = useRoomContext();
30
-
31
- const handleConnect = () => {
32
- if (liveKitConnection) {
33
- setLiveKitConnection(false);
34
- setLiveKitRoom(`${v4()}`);
35
- setLiveKitToken('');
36
- room.disconnect(true);
37
- return;
38
- }
39
- setLiveKitRoom(roomName);
40
- const fetchToken = async () => {
41
- try {
42
- const res = await fetch(
43
- `/livekit-token?room=${roomName}&username=${username}`,
44
- {
45
- method: 'GET',
46
- },
47
- );
48
- const tokenResponse = await res.text();
49
- setLiveKitToken(tokenResponse);
50
- setLiveKitConnection(true);
51
- } catch (error) {
52
- console.error('Error fetching token:', error);
53
- }
54
- };
55
-
56
- fetchToken();
57
- };
58
-
59
- const handleClose = () => {
60
- setVoiceChatModalOpen(false);
61
- };
62
-
63
- return (
64
- <Modal
65
- className="vz-settings"
66
- show={voiceChatModalOpen}
67
- onHide={handleClose}
68
- animation={false}
69
- >
70
- <Modal.Header closeButton>
71
- <Modal.Title>Connect to LiveKit Room</Modal.Title>
72
- </Modal.Header>
73
- <Modal.Body>
74
- <Form>
75
- <Form.Group controlId="formRoomName">
76
- <Form.Label>Room Name</Form.Label>
77
- <Form.Control
78
- type="text"
79
- placeholder="Enter room name"
80
- value={roomName}
81
- onChange={(e) => setRoomName(e.target.value)}
82
- />
83
- </Form.Group>
84
- </Form>
85
- <Form>
86
- <Form.Group controlId="formUserName">
87
- <Form.Label>Username</Form.Label>
88
- <Form.Control
89
- type="text"
90
- placeholder="Enter Username"
91
- value={username}
92
- onChange={(e) => setUsername(e.target.value)}
93
- />
94
- </Form.Group>
95
- </Form>
96
- <div
97
- style={{
98
- display: 'flex',
99
- flexDirection: 'column',
100
- }}
101
- >
102
- <b>Users in Room: </b>
103
- <ParticipantLoop participants={participants}>
104
- <ParticipantName />
105
- </ParticipantLoop>
106
- </div>
107
- </Modal.Body>
108
- <Modal.Footer>
109
- <Button variant="secondary" onClick={handleClose}>
110
- Cancel
111
- </Button>
112
- <Button
113
- variant={liveKitConnection ? 'danger' : 'primary'}
114
- onClick={handleConnect}
115
- >
116
- {liveKitConnection ? 'Disconnect' : 'Connect'}
117
- </Button>
118
- </Modal.Footer>
119
- </Modal>
120
- );
121
- }
@@ -1,199 +0,0 @@
1
- import {
2
- formatMarkdownFiles,
3
- parseMarkdownFiles,
4
- } from 'llm-code-format';
5
- import {
6
- FORMAT_INSTRUCTIONS,
7
- mergeFileChanges,
8
- } from 'editcodewithai';
9
- import { VizFiles } from '@vizhub/viz-types';
10
- import {
11
- generateRunId,
12
- vizFilesToFileCollection,
13
- } from '@vizhub/viz-utils';
14
- import JSZip from 'jszip';
15
- import { generate } from '@langchain/core/dist/utils/fast-json-patch';
16
-
17
- export const createAICopyPasteHandlers = (
18
- files: VizFiles,
19
- submitOperation: any,
20
- setCopyButtonText: (text: string) => void,
21
- setPasteButtonText: (text: string) => void,
22
- setExportButtonText: (text: string) => void,
23
- ) => {
24
- // Copy for AI - formats all files and copies to clipboard
25
- const handleCopyForAI = async () => {
26
- if (!files || Object.keys(files).length === 0) {
27
- setCopyButtonText('No files to copy');
28
- setTimeout(
29
- () => setCopyButtonText('Copy for AI'),
30
- 2000,
31
- );
32
- return;
33
- }
34
-
35
- try {
36
- const fileCollection =
37
- vizFilesToFileCollection(files);
38
-
39
- // Format files for AI consumption
40
- const formattedFiles =
41
- formatMarkdownFiles(fileCollection) +
42
- '\n\n' +
43
- FORMAT_INSTRUCTIONS.whole;
44
-
45
- // Copy to clipboard
46
- await navigator.clipboard.writeText(formattedFiles);
47
-
48
- // Show success feedback
49
- setCopyButtonText('Copied!');
50
- setTimeout(
51
- () => setCopyButtonText('Copy for AI'),
52
- 2000,
53
- );
54
- } catch (error) {
55
- console.error('Failed to copy files for AI:', error);
56
- setCopyButtonText('Error');
57
- setTimeout(
58
- () => setCopyButtonText('Copy for AI'),
59
- 2000,
60
- );
61
- }
62
- };
63
-
64
- // Paste for AI - parses clipboard content and updates files
65
- const handlePasteForAI = async () => {
66
- if (!submitOperation) return;
67
-
68
- try {
69
- // Read from clipboard
70
- const clipboardText =
71
- await navigator.clipboard.readText();
72
-
73
- // Handle various line endings
74
- const normalized = clipboardText.replace(
75
- /\r\n?/g,
76
- '\n',
77
- );
78
-
79
- if (!normalized.trim()) {
80
- setPasteButtonText('Empty clipboard');
81
- setTimeout(
82
- () => setPasteButtonText('Paste for AI'),
83
- 2000,
84
- );
85
- return;
86
- }
87
-
88
- // Preprocess to remove formatting instructions section to avoid creating extra files
89
- const preprocessed = normalized
90
- .split('## Formatting Instructions')[0]
91
- .trim();
92
-
93
- // Parse the markdown files format
94
- const parsed = parseMarkdownFiles(
95
- preprocessed,
96
- 'bold',
97
- );
98
-
99
- if (
100
- parsed.files &&
101
- Object.keys(parsed.files).length > 0
102
- ) {
103
- // Use mergeFileChanges utility from editcodewithai
104
- const mergedFiles = mergeFileChanges(
105
- files || {},
106
- parsed.files,
107
- );
108
-
109
- // Update files using the submit operation
110
- submitOperation((document) => ({
111
- ...document,
112
- files: mergedFiles,
113
- runId: generateRunId(),
114
- }));
115
-
116
- const fileCount = Object.keys(parsed.files).length;
117
- setPasteButtonText('Pasted!');
118
- setTimeout(
119
- () => setPasteButtonText('Paste for AI'),
120
- 2000,
121
- );
122
- } else {
123
- setPasteButtonText('No files found');
124
- setTimeout(
125
- () => setPasteButtonText('Paste for AI'),
126
- 2000,
127
- );
128
- }
129
- } catch (error) {
130
- console.error(
131
- 'Failed to paste files from AI:',
132
- error,
133
- );
134
- setPasteButtonText('Error');
135
- setTimeout(
136
- () => setPasteButtonText('Paste for AI'),
137
- 2000,
138
- );
139
- }
140
- };
141
-
142
- // Export to ZIP - creates and downloads a ZIP file with all viz files
143
- const handleExportToZip = async () => {
144
- if (!files || Object.keys(files).length === 0) {
145
- setExportButtonText('No files to export');
146
- setTimeout(
147
- () => setExportButtonText('Export to ZIP'),
148
- 2000,
149
- );
150
- return;
151
- }
152
-
153
- try {
154
- // Create the ZIP
155
- const zip = new JSZip();
156
-
157
- // Add each file to the ZIP
158
- Object.entries(files).forEach(([fileId, file]) => {
159
- const fileName = file.name || fileId;
160
- const fileContent = file.text || '';
161
- zip.file(fileName, fileContent);
162
- });
163
-
164
- // Generate and download
165
- const blob = await zip.generateAsync({
166
- type: 'blob',
167
- });
168
- const url = URL.createObjectURL(blob);
169
- const a = document.createElement('a');
170
- a.href = url;
171
- a.download = 'viz-files.zip';
172
- a.click();
173
- URL.revokeObjectURL(url);
174
-
175
- // Show success feedback
176
- setExportButtonText('Exported!');
177
- setTimeout(
178
- () => setExportButtonText('Export to ZIP'),
179
- 2000,
180
- );
181
- } catch (error) {
182
- console.error(
183
- 'Failed to export files to ZIP:',
184
- error,
185
- );
186
- setExportButtonText('Error');
187
- setTimeout(
188
- () => setExportButtonText('Export to ZIP'),
189
- 2000,
190
- );
191
- }
192
- };
193
-
194
- return {
195
- handleCopyForAI,
196
- handlePasteForAI,
197
- handleExportToZip,
198
- };
199
- };