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.
- package/dist/assets/{buildWorker-Dsx6rOdK.js → buildWorker-wLkQ0yz1.js} +64 -64
- package/dist/assets/{index-BM8tDh6M.css → index-BoFeK4GL.css} +1 -1
- package/dist/assets/{index-BgqNq-ww.js → index-DuUjtrt6.js} +107 -107
- package/dist/assets/{worker-BeBZGG1n.js → worker-DHxSPM7N.js} +78 -78
- package/dist/cli.js +113 -0
- package/dist/index.html +2 -2
- package/{src/ot.ts → dist/ot.js} +2 -14
- package/{src/randomId.ts → dist/randomId.js} +5 -6
- package/dist/runCode.js +20 -0
- package/dist/server/aiChatHandler/aiEditing.js +89 -0
- package/dist/server/aiChatHandler/chatOperations.js +360 -0
- package/dist/server/aiChatHandler/errorHandling.js +49 -0
- package/dist/server/aiChatHandler/index.js +112 -0
- package/dist/server/aiChatHandler/llmStreaming.js +284 -0
- package/dist/server/aiChatHandler/validation.js +19 -0
- package/dist/server/computeInitialDocument.js +146 -0
- package/{src/server/config.ts → dist/server/config.js} +4 -7
- package/{src/server/featureFlags.ts → dist/server/featureFlags.js} +0 -3
- package/dist/server/generateAIResponse.js +129 -0
- package/dist/server/handleAIAssist.js +39 -0
- package/dist/server/handleAICopilot.js +81 -0
- package/dist/server/index.js +297 -0
- package/dist/server/livekit.js +17 -0
- package/dist/server/prettier.js +90 -0
- package/{src/server/setupEnv.ts → dist/server/setupEnv.js} +1 -2
- package/dist/submitOperation.js +14 -0
- package/dist/types.js +1 -0
- package/dist/utils/fileDiff.js +66 -0
- package/package.json +23 -22
- package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +0 -42
- package/src/client/AIAssist/AIAssistWidget/index.tsx +0 -135
- package/src/client/AIAssist/AIAssistWidget/style.scss +0 -47
- package/src/client/AIAssist/Spinner.jsx +0 -76
- package/src/client/AIAssist/formatFile.ts +0 -27
- package/src/client/AIAssist/generateFilesContext.ts +0 -25
- package/src/client/AIAssist/index.ts +0 -2
- package/src/client/AIAssist/startAIAssist.ts +0 -95
- package/src/client/App/index.tsx +0 -153
- package/src/client/App/style.scss +0 -82
- package/src/client/App/usePending.ts +0 -51
- package/src/client/App/useShareDB.ts +0 -161
- package/src/client/CodeEditor/Copilot/index.ts +0 -74
- package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +0 -12
- package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +0 -68
- package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +0 -174
- package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +0 -79
- package/src/client/CodeEditor/InteractiveWidgets/index.ts +0 -44
- package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +0 -12
- package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +0 -20
- package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +0 -143
- package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +0 -48
- package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +0 -12
- package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +0 -25
- package/src/client/CodeEditor/basicSetup.ts +0 -73
- package/src/client/CodeEditor/getOrCreateEditor.tsx +0 -615
- package/src/client/CodeEditor/index.tsx +0 -202
- package/src/client/CodeEditor/json1PresenceBroadcast.ts +0 -41
- package/src/client/CodeEditor/json1PresenceDisplay.ts +0 -350
- package/src/client/CodeEditor/rainbowBrackets.ts +0 -122
- package/src/client/CodeEditor/style.scss +0 -156
- package/src/client/CodeEditor/typescriptExtension/worker.ts +0 -32
- package/src/client/CodeErrorOverlay/index.tsx +0 -77
- package/src/client/CodeErrorOverlay/style.scss +0 -33
- package/src/client/Fonts/fonts.ts +0 -8
- package/src/client/Icons/AdjustmentSVG.tsx +0 -19
- package/src/client/Icons/BugSVG.tsx +0 -20
- package/src/client/Icons/CloseSVG.tsx +0 -19
- package/src/client/Icons/CssSVG.tsx +0 -16
- package/src/client/Icons/DirectoryArrowSVG.tsx +0 -19
- package/src/client/Icons/EditSVG.tsx +0 -19
- package/src/client/Icons/FileSVG.tsx +0 -19
- package/src/client/Icons/FolderSVG.tsx +0 -20
- package/src/client/Icons/GearSVG.tsx +0 -16
- package/src/client/Icons/HtmlSVG.tsx +0 -16
- package/src/client/Icons/JavaScriptSVG.tsx +0 -16
- package/src/client/Icons/JsonSVG.tsx +0 -16
- package/src/client/Icons/MarkdownSVG.tsx +0 -16
- package/src/client/Icons/MicSVG.tsx +0 -25
- package/src/client/Icons/NewSVG.tsx +0 -19
- package/src/client/Icons/PinSVG.tsx +0 -14
- package/src/client/Icons/PlaySVG.tsx +0 -16
- package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
- package/src/client/Icons/ReactSVG.tsx +0 -16
- package/src/client/Icons/SearchSVG.tsx +0 -20
- package/src/client/Icons/SparklesSVG.tsx +0 -23
- package/src/client/Icons/SplitEditorSVG.tsx +0 -34
- package/src/client/Icons/StopSVG.tsx +0 -15
- package/src/client/Icons/SvelteSVG.tsx +0 -16
- package/src/client/Icons/TrashSVG.tsx +0 -19
- package/src/client/Icons/TypeScriptSVG.tsx +0 -16
- package/src/client/Icons/index.tsx +0 -24
- package/src/client/ImageViewer/index.tsx +0 -91
- package/src/client/ImageViewer/style.scss +0 -41
- package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
- package/src/client/PresenceNotifications/index.tsx +0 -158
- package/src/client/PresenceNotifications/style.scss +0 -17
- package/src/client/RunCodeWidget/index.tsx +0 -117
- package/src/client/RunCodeWidget/style.scss +0 -24
- package/src/client/SplitPaneResizeContext.tsx +0 -159
- package/src/client/TabList/Tab.tsx +0 -73
- package/src/client/TabList/index.tsx +0 -35
- package/src/client/TabList/style.scss +0 -51
- package/src/client/VZCodeContext/index.tsx +0 -29
- package/src/client/VZCodeContext/types.ts +0 -249
- package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
- package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
- package/src/client/VZLeft.tsx +0 -28
- package/src/client/VZMiddle.tsx +0 -172
- package/src/client/VZResizer/index.tsx +0 -128
- package/src/client/VZResizer/styles.scss +0 -33
- package/src/client/VZRight.tsx +0 -113
- package/src/client/VZSettings.tsx +0 -275
- package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -196
- package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
- package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
- package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
- package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
- package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
- package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
- package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
- package/src/client/VZSidebar/AIChat/index.tsx +0 -273
- package/src/client/VZSidebar/AIChat/styles.scss +0 -627
- package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
- package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
- package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
- package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
- package/src/client/VZSidebar/EmptyState.tsx +0 -11
- package/src/client/VZSidebar/FileListing.tsx +0 -91
- package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
- package/src/client/VZSidebar/Item.tsx +0 -237
- package/src/client/VZSidebar/Listing.tsx +0 -47
- package/src/client/VZSidebar/Search.tsx +0 -527
- package/src/client/VZSidebar/VisualEditor.tsx +0 -295
- package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
- package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
- package/src/client/VZSidebar/index.tsx +0 -728
- package/src/client/VZSidebar/styles.scss +0 -612
- package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
- package/src/client/bootstrap.ts +0 -26
- package/src/client/buildWorker.ts +0 -3
- package/src/client/featureFlags.ts +0 -8
- package/src/client/generateRequestId.ts +0 -6
- package/src/client/getFileTree.ts +0 -53
- package/src/client/index.ts +0 -19
- package/src/client/main.jsx +0 -10
- package/src/client/presenceColor.ts +0 -8
- package/src/client/shouldTriggerRun.ts +0 -31
- package/src/client/sortFileTree.ts +0 -21
- package/src/client/tabsSearchParameters.test.ts +0 -79
- package/src/client/tabsSearchParameters.ts +0 -137
- package/src/client/themes/index.ts +0 -7
- package/src/client/themes/themes.ts +0 -77
- package/src/client/themes/uiwImports.ts +0 -32
- package/src/client/themes/useDynamicTheme.ts +0 -29
- package/src/client/themes/vizhubTheme/colors.ts +0 -80
- package/src/client/themes/vizhubTheme/index.ts +0 -193
- package/src/client/useActions.ts +0 -288
- package/src/client/useESLint/index.ts +0 -72
- package/src/client/useESLint/worker.ts +0 -113
- package/src/client/useEditorCache.ts +0 -35
- package/src/client/useFileCRUD.ts +0 -228
- package/src/client/useKeyboardShortcuts.ts +0 -451
- package/src/client/useOpenDirectories.ts +0 -99
- package/src/client/usePresenceAutoFollow.ts +0 -85
- package/src/client/usePrettier/index.ts +0 -178
- package/src/client/usePrettier/worker.ts +0 -109
- package/src/client/useRunCode.tsx +0 -15
- package/src/client/useRuntimeError.ts +0 -32
- package/src/client/useSubmitOperation.ts +0 -15
- package/src/client/useURLSync.ts +0 -137
- package/src/client/usernameLocalStorage.ts +0 -43
- package/src/client/utils/fileExtension.ts +0 -10
- package/src/client/utils/isImageFile.ts +0 -12
- package/src/client/vzReducer/aiChatReducer.ts +0 -44
- package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
- package/src/client/vzReducer/closeTabsReducer.ts +0 -96
- package/src/client/vzReducer/createInitialState.ts +0 -38
- package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
- package/src/client/vzReducer/findPane.ts +0 -19
- package/src/client/vzReducer/index.ts +0 -250
- package/src/client/vzReducer/openTabReducer.test.ts +0 -127
- package/src/client/vzReducer/openTabReducer.ts +0 -74
- package/src/client/vzReducer/searchReducer.test.ts +0 -292
- package/src/client/vzReducer/searchReducer.ts +0 -181
- package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
- package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
- package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
- package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
- package/src/client/vzReducer/setThemeReducer.ts +0 -9
- package/src/client/vzReducer/setUsernameReducer.ts +0 -9
- package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
- package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
- package/src/client/vzReducer/updatePane.ts +0 -40
- package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
- package/src/client/vzReducer/visualEditorReducer.ts +0 -9
- package/src/reactRouterExports.ts +0 -15
- package/src/runCode.ts +0 -27
- package/src/server/aiChatHandler/aiEditing.ts +0 -152
- package/src/server/aiChatHandler/chatOperations.ts +0 -510
- package/src/server/aiChatHandler/errorHandling.ts +0 -66
- package/src/server/aiChatHandler/index.ts +0 -200
- package/src/server/aiChatHandler/llmStreaming.ts +0 -419
- package/src/server/aiChatHandler/undoHandler.ts +0 -97
- package/src/server/aiChatHandler/validation.ts +0 -24
- package/src/server/computeInitialDocument.ts +0 -220
- package/src/server/generateAIResponse.ts +0 -188
- package/src/server/handleAIAssist.ts +0 -53
- package/src/server/handleAIChatUndo.ts +0 -2
- package/src/server/handleAICopilot.ts +0 -97
- package/src/server/index.ts +0 -388
- package/src/server/livekit.ts +0 -24
- package/src/server/prettier.ts +0 -115
- package/src/submitOperation.ts +0 -25
- package/src/types.ts +0 -205
- package/src/utils/fileDiff.ts +0 -117
- package/src/vite-env.d.ts +0 -10
- /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
- /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
|
-
};
|