vzcode 1.19.0 → 1.20.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/{index-CSSpCKM0.js → index-DxgQGuCb.js} +101 -101
- package/dist/assets/index-w9VAfRwW.js +192 -0
- package/dist/assets/{worker-8af7bTHW.js → worker-B9Dbsldy.js} +179 -179
- package/dist/index.html +1 -1
- package/package.json +38 -38
- package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +14 -14
- package/src/client/CodeEditor/getOrCreateEditor.ts +22 -10
- package/src/client/CodeEditor/style.scss +26 -26
- package/src/client/RunCodeWidget/index.tsx +11 -3
- package/src/client/VZKeyboardShortcutsDoc.tsx +34 -8
- package/src/client/VZSettings.tsx +109 -118
- package/src/server/handleAICopilot.js +2 -2
- package/dist/assets/index-DIcMeAET.js +0 -181
|
@@ -8,17 +8,66 @@ import React, {
|
|
|
8
8
|
import { Button, Modal, Form } from './bootstrap';
|
|
9
9
|
import { ThemeLabel, themes } from './themes';
|
|
10
10
|
import { VZCodeContext } from './VZCodeContext';
|
|
11
|
-
import { fonts } from './Fonts/fonts';
|
|
12
|
-
import { toggleRainbowBrackets } from './CodeEditor/rainbowBrackets';
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
// Font size options for the editor
|
|
13
|
+
const fontSizes = [
|
|
14
|
+
'10px',
|
|
15
|
+
'12px',
|
|
16
|
+
'14px',
|
|
17
|
+
'16px',
|
|
18
|
+
'18px',
|
|
19
|
+
'20px',
|
|
20
|
+
'24px',
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
// List of system fonts to be detected for availability
|
|
24
|
+
const systemFonts = [
|
|
25
|
+
'-apple-system',
|
|
26
|
+
'BlinkMacSystemFont',
|
|
27
|
+
'Segoe UI',
|
|
28
|
+
'Roboto',
|
|
29
|
+
'Helvetica Neue',
|
|
30
|
+
'Arial',
|
|
31
|
+
'sans-serif',
|
|
32
|
+
'Courier New',
|
|
33
|
+
'Georgia',
|
|
34
|
+
'Tahoma',
|
|
35
|
+
'Verdana',
|
|
36
|
+
'Times New Roman',
|
|
37
|
+
'Trebuchet MS',
|
|
38
|
+
'Comic Sans MS',
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
// Utility function to detect if a given font is available
|
|
42
|
+
const isFontAvailable = (font: string): boolean => {
|
|
43
|
+
const testString = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
44
|
+
const testSize = '72px';
|
|
45
|
+
|
|
46
|
+
const span = document.createElement('span');
|
|
47
|
+
span.style.fontSize = testSize;
|
|
48
|
+
span.style.visibility = 'hidden';
|
|
49
|
+
span.style.position = 'absolute';
|
|
50
|
+
span.innerHTML = testString;
|
|
51
|
+
document.body.appendChild(span);
|
|
52
|
+
|
|
53
|
+
const defaultFont = 'monospace';
|
|
54
|
+
span.style.fontFamily = defaultFont;
|
|
55
|
+
const defaultWidth = span.offsetWidth;
|
|
56
|
+
|
|
57
|
+
span.style.fontFamily = `${font}, ${defaultFont}`;
|
|
58
|
+
const newWidth = span.offsetWidth;
|
|
59
|
+
|
|
60
|
+
document.body.removeChild(span);
|
|
61
|
+
|
|
62
|
+
return newWidth !== defaultWidth;
|
|
63
|
+
};
|
|
15
64
|
|
|
16
65
|
export const VZSettings = ({
|
|
17
66
|
enableUsernameField = true,
|
|
18
67
|
}: {
|
|
19
|
-
// Feature flag to enable/disable username field
|
|
20
68
|
enableUsernameField?: boolean;
|
|
21
69
|
}) => {
|
|
70
|
+
// Extracting context values for managing settings state
|
|
22
71
|
const {
|
|
23
72
|
isSettingsOpen,
|
|
24
73
|
closeSettings,
|
|
@@ -28,58 +77,24 @@ export const VZSettings = ({
|
|
|
28
77
|
setUsername,
|
|
29
78
|
} = useContext(VZCodeContext);
|
|
30
79
|
|
|
31
|
-
|
|
32
|
-
(event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
33
|
-
const selectedTheme = event.target.value as ThemeLabel;
|
|
34
|
-
setTheme(selectedTheme);
|
|
35
|
-
localStorage.setItem('vzcodeSelectedTheme', selectedTheme);
|
|
36
|
-
},
|
|
37
|
-
[],
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
const savedTheme = localStorage.getItem('vzcodeSelectedTheme') as ThemeLabel | null;
|
|
42
|
-
if (savedTheme) {
|
|
43
|
-
setTheme(savedTheme);
|
|
44
|
-
} else {
|
|
45
|
-
setTheme('vizhub');
|
|
46
|
-
}
|
|
47
|
-
}, [setTheme]);
|
|
48
|
-
// Initialize font and size from localStorage or defaults
|
|
49
|
-
// const [selectedFont, setSelectedFont] = useState(
|
|
50
|
-
// localStorage.getItem('vzcodeSelectedFont') ||
|
|
51
|
-
// 'Roboto Mono',
|
|
52
|
-
// );
|
|
53
|
-
// const [selectedFontSize, setSelectedFontSize] = useState(
|
|
54
|
-
// localStorage.getItem('vzcodeSelectedFontSize') ||
|
|
55
|
-
// '16px',
|
|
56
|
-
// );
|
|
80
|
+
// State variables for managing font and font size
|
|
57
81
|
const [selectedFont, setSelectedFont] =
|
|
58
82
|
useState('Roboto Mono');
|
|
59
83
|
const [selectedFontSize, setSelectedFontSize] =
|
|
60
84
|
useState('16px');
|
|
85
|
+
const [availableFonts, setAvailableFonts] = useState<
|
|
86
|
+
string[]
|
|
87
|
+
>([]);
|
|
61
88
|
|
|
62
|
-
//
|
|
63
|
-
const [rainbowBrackets, setRainbowBrackets] =
|
|
64
|
-
useState('on');
|
|
65
|
-
|
|
89
|
+
// Load saved settings from local storage on initial render
|
|
66
90
|
useEffect(() => {
|
|
67
|
-
// If we're in the browser,
|
|
68
91
|
if (typeof window !== 'undefined') {
|
|
69
|
-
const selectedFontFromLocalStorage
|
|
92
|
+
const selectedFontFromLocalStorage =
|
|
70
93
|
window.localStorage.getItem('vzcodeSelectedFont');
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
'vzcodeSelectedFontSize',
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const rainbowBracketsFromLocalStorage:
|
|
79
|
-
| string
|
|
80
|
-
| null = window.localStorage.getItem(
|
|
81
|
-
'vzcodeRainbowBrackets',
|
|
82
|
-
);
|
|
94
|
+
const selectedFontSizeFromLocalStorage =
|
|
95
|
+
window.localStorage.getItem(
|
|
96
|
+
'vzcodeSelectedFontSize',
|
|
97
|
+
);
|
|
83
98
|
|
|
84
99
|
if (selectedFontFromLocalStorage !== null) {
|
|
85
100
|
setSelectedFont(selectedFontFromLocalStorage);
|
|
@@ -89,48 +104,42 @@ export const VZSettings = ({
|
|
|
89
104
|
selectedFontSizeFromLocalStorage,
|
|
90
105
|
);
|
|
91
106
|
}
|
|
92
|
-
if (rainbowBracketsFromLocalStorage !== null) {
|
|
93
|
-
setRainbowBrackets(rainbowBracketsFromLocalStorage);
|
|
94
|
-
}
|
|
95
|
-
} else {
|
|
96
|
-
// If we're not in the browser, use the default initial width.
|
|
97
107
|
}
|
|
98
108
|
}, []);
|
|
99
109
|
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
(
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
// Detect available system fonts and update the state
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
const detectFonts = () => {
|
|
113
|
+
const detectedFonts: string[] = [];
|
|
114
|
+
for (const font of systemFonts) {
|
|
115
|
+
if (isFontAvailable(font)) {
|
|
116
|
+
detectedFonts.push(font);
|
|
117
|
+
if (process.env.NODE_ENV === 'development') {
|
|
118
|
+
console.log(`${font} is available`);
|
|
119
|
+
}
|
|
120
|
+
} else if (process.env.NODE_ENV === 'development') {
|
|
121
|
+
console.log(`${font} is not available`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
setAvailableFonts(detectedFonts);
|
|
125
|
+
};
|
|
109
126
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
(event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
113
|
-
const newSize = event.target.value;
|
|
114
|
-
localStorage.setItem(
|
|
115
|
-
'vzcodeSelectedFontSize',
|
|
116
|
-
newSize,
|
|
117
|
-
);
|
|
118
|
-
setSelectedFontSize(newSize);
|
|
119
|
-
},
|
|
120
|
-
[],
|
|
121
|
-
);
|
|
127
|
+
detectFonts();
|
|
128
|
+
}, []);
|
|
122
129
|
|
|
123
|
-
//
|
|
124
|
-
const
|
|
125
|
-
(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
// Reset all settings to default values
|
|
131
|
+
const resetSettings = useCallback(() => {
|
|
132
|
+
setSelectedFont('Roboto Mono');
|
|
133
|
+
setSelectedFontSize('16px');
|
|
134
|
+
setTheme(themes[0].label);
|
|
135
|
+
if (enableUsernameField) {
|
|
136
|
+
setUsername('');
|
|
137
|
+
}
|
|
138
|
+
localStorage.removeItem('vzcodeSelectedFont');
|
|
139
|
+
localStorage.removeItem('vzcodeSelectedFontSize');
|
|
140
|
+
}, [enableUsernameField, setTheme, setUsername]);
|
|
133
141
|
|
|
142
|
+
// Update font family in the document's style
|
|
134
143
|
useEffect(() => {
|
|
135
144
|
document.body.style.setProperty(
|
|
136
145
|
'--vzcode-font-family',
|
|
@@ -138,6 +147,7 @@ export const VZSettings = ({
|
|
|
138
147
|
);
|
|
139
148
|
}, [selectedFont]);
|
|
140
149
|
|
|
150
|
+
// Update font size in the document's style
|
|
141
151
|
useEffect(() => {
|
|
142
152
|
document.body.style.setProperty(
|
|
143
153
|
'--vzcode-font-size',
|
|
@@ -147,11 +157,12 @@ export const VZSettings = ({
|
|
|
147
157
|
|
|
148
158
|
const usernameRef = useRef<HTMLInputElement>(null);
|
|
149
159
|
|
|
160
|
+
// Handle username input change
|
|
150
161
|
const handleUsernameChange = useCallback(() => {
|
|
151
162
|
setUsername(usernameRef.current?.value || '');
|
|
152
163
|
}, [setUsername]);
|
|
153
164
|
|
|
154
|
-
//
|
|
165
|
+
// Close settings modal on Enter key press
|
|
155
166
|
useEffect(() => {
|
|
156
167
|
if (isSettingsOpen) {
|
|
157
168
|
const handleEnterKey = (event: KeyboardEvent) => {
|
|
@@ -203,7 +214,9 @@ export const VZSettings = ({
|
|
|
203
214
|
<select
|
|
204
215
|
className="form-select"
|
|
205
216
|
value={theme}
|
|
206
|
-
onChange={
|
|
217
|
+
onChange={(e) =>
|
|
218
|
+
setTheme(e.target.value as ThemeLabel)
|
|
219
|
+
}
|
|
207
220
|
>
|
|
208
221
|
{themes.map(({ label }) => (
|
|
209
222
|
<option key={label} value={label}>
|
|
@@ -211,37 +224,32 @@ export const VZSettings = ({
|
|
|
211
224
|
</option>
|
|
212
225
|
))}
|
|
213
226
|
</select>
|
|
214
|
-
<Form.Text className="text-muted">
|
|
215
|
-
Select a color theme for the editor
|
|
216
|
-
</Form.Text>
|
|
217
227
|
</Form.Group>
|
|
218
228
|
|
|
219
229
|
<Form.Group className="mb-3" controlId="formFork">
|
|
220
230
|
<Form.Label>Font</Form.Label>
|
|
221
|
-
|
|
222
231
|
<select
|
|
223
232
|
className="form-select"
|
|
224
|
-
onChange={
|
|
233
|
+
onChange={(e) =>
|
|
234
|
+
setSelectedFont(e.target.value)
|
|
235
|
+
}
|
|
225
236
|
value={selectedFont}
|
|
226
237
|
>
|
|
227
|
-
{
|
|
238
|
+
{availableFonts.map((font) => (
|
|
228
239
|
<option key={font} value={font}>
|
|
229
240
|
{font}
|
|
230
241
|
</option>
|
|
231
242
|
))}
|
|
232
243
|
</select>
|
|
233
|
-
|
|
234
|
-
<Form.Text className="text-muted">
|
|
235
|
-
Select font for the editor
|
|
236
|
-
</Form.Text>
|
|
237
244
|
</Form.Group>
|
|
238
245
|
|
|
239
246
|
<Form.Group className="mb-3" controlId="formFork">
|
|
240
247
|
<Form.Label>Font Size</Form.Label>
|
|
241
|
-
|
|
242
248
|
<select
|
|
243
249
|
className="form-select"
|
|
244
|
-
onChange={
|
|
250
|
+
onChange={(e) =>
|
|
251
|
+
setSelectedFontSize(e.target.value)
|
|
252
|
+
}
|
|
245
253
|
value={selectedFontSize}
|
|
246
254
|
>
|
|
247
255
|
{fontSizes.map((size) => (
|
|
@@ -250,29 +258,12 @@ export const VZSettings = ({
|
|
|
250
258
|
</option>
|
|
251
259
|
))}
|
|
252
260
|
</select>
|
|
253
|
-
|
|
254
|
-
<Form.Text className="text-muted">
|
|
255
|
-
Select a font size for the editor
|
|
256
|
-
</Form.Text>
|
|
257
|
-
</Form.Group>
|
|
258
|
-
|
|
259
|
-
<Form.Group className="mb-3" controlId="formFork">
|
|
260
|
-
<Form.Label>Rainbow Brackets</Form.Label>
|
|
261
|
-
<select
|
|
262
|
-
className="form-select"
|
|
263
|
-
onChange={handleRainbowBracketsChange}
|
|
264
|
-
value={rainbowBrackets}
|
|
265
|
-
>
|
|
266
|
-
<option value="on">On</option>
|
|
267
|
-
<option value="off">Off</option>
|
|
268
|
-
</select>
|
|
269
|
-
<Form.Text className="text-muted">
|
|
270
|
-
Toggle Rainbow Brackets
|
|
271
|
-
</Form.Text>
|
|
272
261
|
</Form.Group>
|
|
273
|
-
|
|
274
262
|
</Modal.Body>
|
|
275
263
|
<Modal.Footer>
|
|
264
|
+
<Button variant="secondary" onClick={resetSettings}>
|
|
265
|
+
Reset to Default
|
|
266
|
+
</Button>
|
|
276
267
|
<Button variant="primary" onClick={closeSettings}>
|
|
277
268
|
Done
|
|
278
269
|
</Button>
|
|
@@ -38,8 +38,8 @@ if (isCopilotEnabled) {
|
|
|
38
38
|
openai = new OpenAI(openAIOptions);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export const handleAICopilot =
|
|
42
|
-
|
|
41
|
+
export const handleAICopilot = (/*TODO shareDBDoc*/) =>
|
|
42
|
+
async (req, res) => {
|
|
43
43
|
// Don't break if the AI is not enabled.
|
|
44
44
|
// This is useful for local development.
|
|
45
45
|
if (!isCopilotEnabled) {
|