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,275 +0,0 @@
1
- import {
2
- useCallback,
3
- useContext,
4
- useEffect,
5
- useRef,
6
- useState,
7
- } from 'react';
8
- import { Button, Modal, Form } from './bootstrap';
9
- import { ThemeLabel, themes } from './themes';
10
- import { VZCodeContext } from './VZCodeContext';
11
-
12
- const DEBUG = false;
13
-
14
- // Font size options for the editor
15
- const fontSizes = [
16
- '10px',
17
- '12px',
18
- '14px',
19
- '16px',
20
- '18px',
21
- '20px',
22
- '24px',
23
- ];
24
-
25
- // List of system fonts to be detected for availability
26
- const systemFonts = [
27
- '-apple-system',
28
- 'BlinkMacSystemFont',
29
- 'Segoe UI',
30
- 'Roboto',
31
- 'Helvetica Neue',
32
- 'Arial',
33
- 'sans-serif',
34
- 'Courier New',
35
- 'Georgia',
36
- 'Tahoma',
37
- 'Verdana',
38
- 'Times New Roman',
39
- 'Trebuchet MS',
40
- 'Comic Sans MS',
41
- ];
42
-
43
- // Utility function to detect if a given font is available
44
- const isFontAvailable = (font: string): boolean => {
45
- const testString = 'abcdefghijklmnopqrstuvwxyz0123456789';
46
- const testSize = '72px';
47
-
48
- const span = document.createElement('span');
49
- span.style.fontSize = testSize;
50
- span.style.visibility = 'hidden';
51
- span.style.position = 'absolute';
52
- span.innerHTML = testString;
53
- document.body.appendChild(span);
54
-
55
- const defaultFont = 'monospace';
56
- span.style.fontFamily = defaultFont;
57
- const defaultWidth = span.offsetWidth;
58
-
59
- span.style.fontFamily = `${font}, ${defaultFont}`;
60
- const newWidth = span.offsetWidth;
61
-
62
- document.body.removeChild(span);
63
-
64
- return newWidth !== defaultWidth;
65
- };
66
-
67
- export const VZSettings = ({
68
- enableUsernameField = true,
69
- }: {
70
- enableUsernameField?: boolean;
71
- }) => {
72
- // Extracting context values for managing settings state
73
- const {
74
- isSettingsOpen,
75
- closeSettings,
76
- theme,
77
- setTheme,
78
- username,
79
- setUsername,
80
- } = useContext(VZCodeContext);
81
-
82
- // State variables for managing font and font size
83
- const [selectedFont, setSelectedFont] =
84
- useState('Roboto Mono');
85
- const [selectedFontSize, setSelectedFontSize] =
86
- useState('16px');
87
- const [availableFonts, setAvailableFonts] = useState<
88
- string[]
89
- >([]);
90
-
91
- // Load saved settings from local storage on initial render
92
- useEffect(() => {
93
- if (typeof window !== 'undefined') {
94
- const selectedFontFromLocalStorage =
95
- window.localStorage.getItem('vzcodeSelectedFont');
96
- const selectedFontSizeFromLocalStorage =
97
- window.localStorage.getItem(
98
- 'vzcodeSelectedFontSize',
99
- );
100
-
101
- if (selectedFontFromLocalStorage !== null) {
102
- setSelectedFont(selectedFontFromLocalStorage);
103
- }
104
- if (selectedFontSizeFromLocalStorage !== null) {
105
- setSelectedFontSize(
106
- selectedFontSizeFromLocalStorage,
107
- );
108
- }
109
- }
110
- }, []);
111
-
112
- // Detect available system fonts and update the state
113
- useEffect(() => {
114
- const detectFonts = () => {
115
- const detectedFonts: string[] = [];
116
- for (const font of systemFonts) {
117
- if (isFontAvailable(font)) {
118
- detectedFonts.push(font);
119
- if (DEBUG) {
120
- console.log(`${font} is available`);
121
- }
122
- } else if (DEBUG) {
123
- console.log(`${font} is not available`);
124
- }
125
- }
126
- setAvailableFonts(detectedFonts);
127
- };
128
-
129
- detectFonts();
130
- }, []);
131
-
132
- // Reset all settings to default values
133
- const resetSettings = useCallback(() => {
134
- setSelectedFont('Roboto Mono');
135
- setSelectedFontSize('16px');
136
- setTheme(themes[0].label);
137
- if (enableUsernameField) {
138
- setUsername('');
139
- }
140
- localStorage.removeItem('vzcodeSelectedFont');
141
- localStorage.removeItem('vzcodeSelectedFontSize');
142
- }, [enableUsernameField, setTheme, setUsername]);
143
-
144
- // Update font family in the document's style
145
- useEffect(() => {
146
- document.body.style.setProperty(
147
- '--vzcode-font-family',
148
- selectedFont,
149
- );
150
- }, [selectedFont]);
151
-
152
- // Update font size in the document's style
153
- useEffect(() => {
154
- document.body.style.setProperty(
155
- '--vzcode-font-size',
156
- selectedFontSize,
157
- );
158
- }, [selectedFontSize]);
159
-
160
- const usernameRef = useRef<HTMLInputElement>(null);
161
-
162
- // Handle username input change
163
- const handleUsernameChange = useCallback(() => {
164
- setUsername(usernameRef.current?.value || '');
165
- }, [setUsername]);
166
-
167
- // Close settings modal on Enter key press
168
- useEffect(() => {
169
- if (isSettingsOpen) {
170
- const handleEnterKey = (event: KeyboardEvent) => {
171
- if (event.key === 'Enter') {
172
- closeSettings();
173
- }
174
- };
175
-
176
- window.addEventListener('keydown', handleEnterKey);
177
- return () => {
178
- window.removeEventListener(
179
- 'keydown',
180
- handleEnterKey,
181
- );
182
- };
183
- }
184
- }, [isSettingsOpen, closeSettings]);
185
-
186
- return isSettingsOpen ? (
187
- <Modal
188
- className="vz-settings"
189
- show={isSettingsOpen}
190
- onHide={closeSettings}
191
- animation={false}
192
- >
193
- <Modal.Header closeButton>
194
- <Modal.Title>Editor Settings</Modal.Title>
195
- </Modal.Header>
196
- <Modal.Body>
197
- {enableUsernameField ? (
198
- <Form.Group className="mb-3" controlId="formFork">
199
- <Form.Label>Username</Form.Label>
200
- <Form.Control
201
- type="text"
202
- ref={usernameRef}
203
- onChange={handleUsernameChange}
204
- placeholder="Enter username"
205
- value={username}
206
- />
207
- <Form.Text className="text-muted">
208
- Enter a username to be displayed on your
209
- cursor
210
- </Form.Text>
211
- </Form.Group>
212
- ) : null}
213
-
214
- <Form.Group className="mb-3" controlId="formFork">
215
- <Form.Label>Theme</Form.Label>
216
- <select
217
- className="form-select"
218
- value={theme}
219
- onChange={(e) =>
220
- setTheme(e.target.value as ThemeLabel)
221
- }
222
- >
223
- {themes.map(({ label }) => (
224
- <option key={label} value={label}>
225
- {label}
226
- </option>
227
- ))}
228
- </select>
229
- </Form.Group>
230
-
231
- <Form.Group className="mb-3" controlId="formFork">
232
- <Form.Label>Font</Form.Label>
233
- <select
234
- className="form-select"
235
- onChange={(e) =>
236
- setSelectedFont(e.target.value)
237
- }
238
- value={selectedFont}
239
- >
240
- {availableFonts.map((font) => (
241
- <option key={font} value={font}>
242
- {font}
243
- </option>
244
- ))}
245
- </select>
246
- </Form.Group>
247
-
248
- <Form.Group className="mb-3" controlId="formFork">
249
- <Form.Label>Font Size</Form.Label>
250
- <select
251
- className="form-select"
252
- onChange={(e) =>
253
- setSelectedFontSize(e.target.value)
254
- }
255
- value={selectedFontSize}
256
- >
257
- {fontSizes.map((size) => (
258
- <option key={size} value={size}>
259
- {size}
260
- </option>
261
- ))}
262
- </select>
263
- </Form.Group>
264
- </Modal.Body>
265
- <Modal.Footer>
266
- <Button variant="secondary" onClick={resetSettings}>
267
- Reset to Default
268
- </Button>
269
- <Button variant="primary" onClick={closeSettings}>
270
- Done
271
- </Button>
272
- </Modal.Footer>
273
- </Modal>
274
- ) : null;
275
- };
@@ -1,239 +0,0 @@
1
- import {
2
- useRef,
3
- useEffect,
4
- useCallback,
5
- memo,
6
- } from 'react';
7
- import {
8
- Form,
9
- Button,
10
- ButtonGroup,
11
- ToggleButton,
12
- } from '../../bootstrap';
13
- import { enableAskMode } from '../../featureFlags';
14
- import { useSpeechRecognition } from './useSpeechRecognition';
15
- import { MicSVG, MicOffSVG } from '../../Icons';
16
-
17
- interface ChatInputProps {
18
- aiChatMessage: string;
19
- setAIChatMessage: (message: string) => void;
20
- onSendMessage: () => void;
21
- isLoading: boolean;
22
- focused: boolean;
23
- aiChatMode: 'ask' | 'edit';
24
- setAIChatMode: (mode: 'ask' | 'edit') => void;
25
- navigateMessageHistoryUp: () => void;
26
- navigateMessageHistoryDown: () => void;
27
- resetMessageHistoryNavigation: () => void;
28
- }
29
-
30
- const ChatInputComponent = ({
31
- aiChatMessage,
32
- setAIChatMessage,
33
- onSendMessage,
34
- isLoading,
35
- focused,
36
- aiChatMode,
37
- setAIChatMode,
38
- navigateMessageHistoryUp,
39
- navigateMessageHistoryDown,
40
- resetMessageHistoryNavigation,
41
- }: ChatInputProps) => {
42
- const inputRef = useRef<HTMLTextAreaElement>(null);
43
-
44
- // Use the speech recognition hook
45
- const {
46
- isSpeaking,
47
- toggleSpeechRecognition,
48
- stopSpeaking,
49
- } = useSpeechRecognition(setAIChatMessage);
50
-
51
- useEffect(() => {
52
- // Focus the input when the AI chat is focused
53
- if (focused && inputRef.current) {
54
- inputRef.current.focus();
55
- }
56
- }, [focused]);
57
-
58
- const handleKeyDown = useCallback(
59
- (event: React.KeyboardEvent) => {
60
- if (event.key === 'Enter' && !event.shiftKey) {
61
- event.preventDefault();
62
- onSendMessage();
63
- } else if (event.key === 'ArrowUp') {
64
- // Only navigate history if cursor is at the beginning of the first line
65
- const textarea =
66
- event.target as HTMLTextAreaElement;
67
- const { selectionStart, value } = textarea;
68
- const lines = value
69
- .substring(0, selectionStart)
70
- .split('\n');
71
-
72
- // Check if we're at the beginning of the first line
73
- if (lines.length === 1 && selectionStart === 0) {
74
- event.preventDefault();
75
- navigateMessageHistoryUp();
76
- }
77
- } else if (event.key === 'ArrowDown') {
78
- // Only navigate history if cursor is at the end of the last line
79
- const textarea =
80
- event.target as HTMLTextAreaElement;
81
- const { selectionStart, value } = textarea;
82
- const remainingText =
83
- value.substring(selectionStart);
84
- const remainingLines = remainingText.split('\n');
85
-
86
- // Check if we're at the end of the last line
87
- if (
88
- remainingLines.length === 1 &&
89
- remainingLines[0] === ''
90
- ) {
91
- event.preventDefault();
92
- navigateMessageHistoryDown();
93
- }
94
- }
95
- },
96
- [
97
- onSendMessage,
98
- navigateMessageHistoryUp,
99
- navigateMessageHistoryDown,
100
- ],
101
- );
102
-
103
- const handleSendClick = useCallback(() => {
104
- // If speech recognition is active, stop it
105
- if (isSpeaking) {
106
- stopSpeaking();
107
- }
108
- onSendMessage();
109
- }, [onSendMessage, isSpeaking, stopSpeaking]);
110
-
111
- const handleChange = useCallback(
112
- (event: React.ChangeEvent<HTMLTextAreaElement>) => {
113
- setAIChatMessage(event.target.value);
114
- // Reset history navigation when user starts typing
115
- resetMessageHistoryNavigation();
116
- },
117
- [setAIChatMessage, resetMessageHistoryNavigation],
118
- );
119
-
120
- return (
121
- <div className="ai-chat-input-container">
122
- {enableAskMode && (
123
- <div
124
- className="ai-chat-mode-toggle"
125
- style={{ marginBottom: '8px' }}
126
- >
127
- <ButtonGroup size="sm">
128
- <ToggleButton
129
- id="ai-chat-mode-ask"
130
- type="radio"
131
- variant={
132
- aiChatMode === 'ask'
133
- ? 'primary'
134
- : 'outline-primary'
135
- }
136
- name="ai-chat-mode"
137
- value="ask"
138
- checked={aiChatMode === 'ask'}
139
- onChange={() => setAIChatMode('ask')}
140
- disabled={isLoading}
141
- >
142
- 💬 Ask
143
- </ToggleButton>
144
- <ToggleButton
145
- id="ai-chat-mode-edit"
146
- type="radio"
147
- variant={
148
- aiChatMode === 'edit'
149
- ? 'primary'
150
- : 'outline-primary'
151
- }
152
- name="ai-chat-mode"
153
- value="edit"
154
- checked={aiChatMode === 'edit'}
155
- onChange={() => setAIChatMode('edit')}
156
- disabled={isLoading}
157
- >
158
- ✏️ Edit
159
- </ToggleButton>
160
- </ButtonGroup>
161
- <div className="ai-chat-mode-description">
162
- {aiChatMode === 'ask'
163
- ? 'Ask questions without editing files'
164
- : 'Get answers and code edits'}
165
- </div>
166
- </div>
167
- )}
168
- <Form.Group className="ai-chat-input-group">
169
- <Form.Control
170
- as="textarea"
171
- rows={5}
172
- value={aiChatMessage}
173
- onChange={handleChange}
174
- onKeyDown={handleKeyDown}
175
- ref={inputRef}
176
- placeholder={
177
- aiChatMode === 'edit'
178
- ? 'Ask me to make code changes...'
179
- : 'Ask me anything about your code...'
180
- }
181
- spellCheck="false"
182
- disabled={isLoading}
183
- aria-label="Chat message input"
184
- />
185
- <div className="ai-chat-input-footer">
186
- <span className="ai-chat-hint">
187
- {aiChatMessage ? 'Press Enter to send' : ''}
188
- </span>
189
- <div style={{ display: 'flex', gap: '8px' }}>
190
- <Button
191
- variant={
192
- isSpeaking ? 'danger' : 'outline-secondary'
193
- }
194
- size="sm"
195
- onClick={toggleSpeechRecognition}
196
- disabled={isLoading}
197
- aria-label={
198
- isSpeaking
199
- ? 'Stop voice typing'
200
- : 'Start voice typing'
201
- }
202
- title={
203
- isSpeaking
204
- ? 'Stop voice typing'
205
- : 'Start voice typing'
206
- }
207
- style={{
208
- borderColor: isSpeaking
209
- ? undefined
210
- : '#dee2e6',
211
- borderRadius: '0.375rem',
212
- borderWidth: '1px',
213
- borderStyle: 'solid',
214
- }}
215
- >
216
- {isSpeaking ? <MicOffSVG /> : <MicSVG />}
217
- </Button>
218
- <Button
219
- variant={
220
- aiChatMessage.trim()
221
- ? 'primary'
222
- : 'outline-secondary'
223
- }
224
- onClick={handleSendClick}
225
- disabled={!aiChatMessage.trim() || isLoading}
226
- className="ai-chat-send-button"
227
- aria-label="Send message"
228
- title="Send message (Enter)"
229
- >
230
- Send
231
- </Button>
232
- </div>
233
- </div>
234
- </Form.Group>
235
- </div>
236
- );
237
- };
238
-
239
- export const ChatInput = memo(ChatInputComponent);
@@ -1,136 +0,0 @@
1
- .diff-view {
2
- margin: 12px 0;
3
-
4
- .diff-summary {
5
- margin-bottom: 8px;
6
- display: flex;
7
- justify-content: space-between;
8
- align-items: center;
9
-
10
- .diff-stats {
11
- display: flex;
12
- align-items: center;
13
- gap: 8px;
14
- font-size: 12px;
15
- color: var(--bs-secondary-color);
16
-
17
- .files-changed {
18
- color: white;
19
- font-weight: 600;
20
- }
21
-
22
- .additions {
23
- color: #28a745;
24
- font-weight: 600;
25
- }
26
-
27
- .deletions {
28
- color: #dc3545;
29
- font-weight: 600;
30
- }
31
- }
32
- }
33
-
34
- .diff-files {
35
- display: flex;
36
- flex-direction: column;
37
- gap: 4px;
38
-
39
- // Fix diff2html styling issues for dark theme and layout
40
- .d2h-wrapper {
41
- // Override diff2html variables for dark theme
42
- --d2h-bg-color: rgb(41, 44, 52);
43
- --d2h-color: #e6edf3;
44
- --d2h-border-color: #30363d;
45
- --d2h-dim-color: #6e7681;
46
- --d2h-info-bg-color: #161b22;
47
- --d2h-file-header-bg-color: #161b22;
48
- --d2h-file-header-border-color: #30363d;
49
- --d2h-line-border-color: #21262d;
50
- --d2h-ins-bg-color: rgba(46, 160, 67, 0.15);
51
- --d2h-ins-border-color: rgba(46, 160, 67, 0.4);
52
- --d2h-ins-highlight-bg-color: rgba(46, 160, 67, 0.4);
53
- --d2h-ins-label-color: #3fb950;
54
- --d2h-del-bg-color: rgba(248, 81, 73, 0.1);
55
- --d2h-del-border-color: rgba(248, 81, 73, 0.4);
56
- --d2h-del-highlight-bg-color: rgba(248, 81, 73, 0.4);
57
- --d2h-del-label-color: #f85149;
58
-
59
- background-color: var(--d2h-bg-color);
60
- color: var(--d2h-color);
61
- border-radius: 6px;
62
- overflow: hidden;
63
- }
64
-
65
- // Fix layout issues with line numbers
66
- .d2h-diff-table {
67
- position: relative;
68
- background-color: var(--d2h-bg-color);
69
- }
70
-
71
- .d2h-code-linenumber {
72
- position: relative !important;
73
- float: none !important;
74
- display: table-cell !important;
75
- width: auto !important;
76
- background-color: var(--d2h-bg-color) !important;
77
- border-color: var(--d2h-line-border-color) !important;
78
- color: var(--d2h-dim-color) !important;
79
- }
80
-
81
- .d2h-code-side-linenumber {
82
- position: relative !important;
83
- float: none !important;
84
- display: table-cell !important;
85
- width: auto !important;
86
- background-color: var(--d2h-bg-color) !important;
87
- border-color: var(--d2h-line-border-color) !important;
88
- color: var(--d2h-dim-color) !important;
89
- }
90
-
91
- // Ensure proper table layout
92
- .d2h-diff-tbody tr {
93
- display: table-row;
94
- }
95
-
96
- .d2h-diff-tbody td {
97
- display: table-cell;
98
- vertical-align: top;
99
- }
100
-
101
- // Fix file header styling
102
- .d2h-file-header {
103
- background-color: var(
104
- --d2h-file-header-bg-color
105
- ) !important;
106
- border-bottom: 1px solid
107
- var(--d2h-file-header-border-color) !important;
108
- color: var(--d2h-color);
109
- }
110
-
111
- // Ensure proper line styling
112
- .d2h-del {
113
- background-color: var(--d2h-del-bg-color) !important;
114
- border-color: var(--d2h-del-border-color) !important;
115
- }
116
-
117
- .d2h-ins {
118
- background-color: var(--d2h-ins-bg-color) !important;
119
- border-color: var(--d2h-ins-border-color) !important;
120
- }
121
-
122
- // Style clickable file names
123
- .d2h-file-name {
124
- &:hover {
125
- text-decoration: underline !important;
126
- opacity: 0.8;
127
- }
128
- }
129
-
130
- // Fix wrapper border
131
- .d2h-file-wrapper {
132
- border: 1px solid var(--d2h-border-color) !important;
133
- background-color: var(--d2h-bg-color);
134
- }
135
- }
136
- }