vzcode 0.71.0 → 0.72.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/README.md +1 -1
- package/dist/assets/{index-HJAv0wn0.js → index-BfS1mzJK.js} +43 -43
- package/dist/assets/index-CpIQ8AoQ.css +1 -0
- package/dist/assets/{worker-D0nKlL79.js → worker-CH5jA9Si.js} +44 -44
- package/dist/index.html +2 -2
- package/package.json +20 -20
- package/src/client/App/index.tsx +2 -0
- package/src/client/App/style.scss +6 -0
- package/src/client/App/useShareDB.ts +12 -0
- package/src/client/CodeEditor/style.scss +4 -0
- package/src/client/Fonts/fonts.ts +8 -0
- package/src/client/VZCodeContext.tsx +6 -0
- package/src/client/VZSettings.tsx +96 -7
- package/src/client/VZSidebar/index.tsx +8 -4
- package/src/client/VZSidebar/styles.scss +13 -11
- package/src/client/useTypeScript/worker.ts +8 -1
- package/dist/assets/index-B4YHcAhs.css +0 -1
package/dist/index.html
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
|
|
21
21
|
rel="stylesheet"
|
|
22
22
|
/>
|
|
23
|
-
<script type="module" crossorigin src="/assets/index-
|
|
24
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
23
|
+
<script type="module" crossorigin src="/assets/index-BfS1mzJK.js"></script>
|
|
24
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CpIQ8AoQ.css">
|
|
25
25
|
</head>
|
|
26
26
|
<body>
|
|
27
27
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vzcode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.72.0",
|
|
4
4
|
"description": "Multiplayer code editor system",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -66,12 +66,12 @@
|
|
|
66
66
|
"@codemirror/autocomplete": "^6.12.0",
|
|
67
67
|
"@codemirror/lang-css": "^6.2.1",
|
|
68
68
|
"@codemirror/lang-html": "^6.4.8",
|
|
69
|
-
"@codemirror/lang-javascript": "^6.2.
|
|
69
|
+
"@codemirror/lang-javascript": "^6.2.2",
|
|
70
70
|
"@codemirror/lang-json": "^6.0.1",
|
|
71
71
|
"@codemirror/lang-markdown": "^6.2.4",
|
|
72
|
-
"@codemirror/state": "^6.4.
|
|
72
|
+
"@codemirror/state": "^6.4.1",
|
|
73
73
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
74
|
-
"@codemirror/view": "^6.24.
|
|
74
|
+
"@codemirror/view": "^6.24.1",
|
|
75
75
|
"@lezer/highlight": "^1.2.0",
|
|
76
76
|
"@replit/codemirror-indentation-markers": "^6.5.0",
|
|
77
77
|
"@replit/codemirror-interact": "^6.3.0",
|
|
@@ -79,27 +79,27 @@
|
|
|
79
79
|
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
|
80
80
|
"@teamwork/websocket-json-stream": "^2.0.0",
|
|
81
81
|
"@typescript/vfs": "^1.5.0",
|
|
82
|
-
"@uiw/codemirror-theme-abcdef": "^4.21.
|
|
83
|
-
"@uiw/codemirror-theme-dracula": "^4.21.
|
|
84
|
-
"@uiw/codemirror-theme-eclipse": "^4.21.
|
|
85
|
-
"@uiw/codemirror-theme-github": "^4.21.
|
|
86
|
-
"@uiw/codemirror-theme-material": "^4.21.
|
|
87
|
-
"@uiw/codemirror-theme-nord": "^4.21.
|
|
88
|
-
"@uiw/codemirror-theme-okaidia": "^4.21.
|
|
89
|
-
"@uiw/codemirror-theme-xcode": "^4.21.
|
|
90
|
-
"@uiw/codemirror-themes": "^4.21.
|
|
82
|
+
"@uiw/codemirror-theme-abcdef": "^4.21.24",
|
|
83
|
+
"@uiw/codemirror-theme-dracula": "^4.21.24",
|
|
84
|
+
"@uiw/codemirror-theme-eclipse": "^4.21.24",
|
|
85
|
+
"@uiw/codemirror-theme-github": "^4.21.24",
|
|
86
|
+
"@uiw/codemirror-theme-material": "^4.21.24",
|
|
87
|
+
"@uiw/codemirror-theme-nord": "^4.21.24",
|
|
88
|
+
"@uiw/codemirror-theme-okaidia": "^4.21.24",
|
|
89
|
+
"@uiw/codemirror-theme-xcode": "^4.21.24",
|
|
90
|
+
"@uiw/codemirror-themes": "^4.21.24",
|
|
91
91
|
"body-parser": "^1.20.2",
|
|
92
92
|
"codemirror": "^6.0.1",
|
|
93
93
|
"codemirror-ot": "^4.2.0",
|
|
94
94
|
"color-hash": "^2.0.2",
|
|
95
95
|
"d3-array": "^3.2.4",
|
|
96
96
|
"diff-match-patch": "^1.0.5",
|
|
97
|
-
"dotenv": "^16.4.
|
|
97
|
+
"dotenv": "^16.4.5",
|
|
98
98
|
"express": "^4.18.2",
|
|
99
99
|
"ignore": "^5.3.1",
|
|
100
100
|
"json0-ot-diff": "^1.1.2",
|
|
101
101
|
"ngrok": "^4.3.3",
|
|
102
|
-
"open": "^10.0.
|
|
102
|
+
"open": "^10.0.4",
|
|
103
103
|
"openai": "^4.28.0",
|
|
104
104
|
"prettier-plugin-svelte": "^3.2.1",
|
|
105
105
|
"react": "^18.2.0",
|
|
@@ -108,18 +108,18 @@
|
|
|
108
108
|
"react-router-dom": "^6.22.1",
|
|
109
109
|
"sharedb": "^4.1.2",
|
|
110
110
|
"sharedb-client-browser": "^4.4.0",
|
|
111
|
-
"vizhub-ui": "^3.
|
|
111
|
+
"vizhub-ui": "^3.21.0",
|
|
112
112
|
"ws": "^8.16.0"
|
|
113
113
|
},
|
|
114
114
|
"devDependencies": {
|
|
115
|
-
"@types/react": "^18.2.
|
|
115
|
+
"@types/react": "^18.2.60",
|
|
116
116
|
"@types/react-dom": "^18.2.19",
|
|
117
117
|
"@vitejs/plugin-react": "^4.2.1",
|
|
118
118
|
"concurrently": "^8.2.2",
|
|
119
119
|
"prettier": "^3.2.5",
|
|
120
|
-
"sass": "^1.71.
|
|
120
|
+
"sass": "^1.71.1",
|
|
121
121
|
"typescript": "^5.3.3",
|
|
122
|
-
"vite": "^5.1.
|
|
123
|
-
"vitest": "^1.3.
|
|
122
|
+
"vite": "^5.1.4",
|
|
123
|
+
"vitest": "^1.3.1"
|
|
124
124
|
}
|
|
125
125
|
}
|
package/src/client/App/index.tsx
CHANGED
|
@@ -61,6 +61,7 @@ function App() {
|
|
|
61
61
|
localPresence,
|
|
62
62
|
docPresence,
|
|
63
63
|
submitOperation,
|
|
64
|
+
connected,
|
|
64
65
|
} = useShareDB({
|
|
65
66
|
connection,
|
|
66
67
|
});
|
|
@@ -87,6 +88,7 @@ function App() {
|
|
|
87
88
|
prettierWorker={prettierWorker}
|
|
88
89
|
typeScriptWorker={typeScriptWorker}
|
|
89
90
|
initialUsername={initialUsername}
|
|
91
|
+
connected={connected}
|
|
90
92
|
>
|
|
91
93
|
<div className="app">
|
|
92
94
|
<VZLeft />
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap');
|
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Inconsolata:wght@200..900&display=swap');
|
|
3
|
+
@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap');
|
|
4
|
+
@import url('https://fonts.googleapis.com/css2?family=Ubuntu+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap');
|
|
5
|
+
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
|
|
6
|
+
@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&display=swap');
|
|
1
7
|
:root {
|
|
2
8
|
// --vzcode-font-family: ui-monospace, SFMono-Regular,
|
|
3
9
|
// 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace !important;
|
|
@@ -28,7 +28,18 @@ export const useShareDB = ({
|
|
|
28
28
|
const [content, setContent] =
|
|
29
29
|
useState<VZCodeContent | null>(null);
|
|
30
30
|
|
|
31
|
+
const [connected, setConnected] =
|
|
32
|
+
useState<boolean>(false);
|
|
31
33
|
useEffect(() => {
|
|
34
|
+
// Listen for connection state changes
|
|
35
|
+
connection.on('connected', () => {
|
|
36
|
+
setConnected(true);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
connection.on('disconnected', () => {
|
|
40
|
+
setConnected(false);
|
|
41
|
+
});
|
|
42
|
+
|
|
32
43
|
// Since there is only ever a single document,
|
|
33
44
|
// these things are pretty arbitrary.
|
|
34
45
|
// * `collection` - the ShareDB collection to use
|
|
@@ -106,5 +117,6 @@ export const useShareDB = ({
|
|
|
106
117
|
localPresence,
|
|
107
118
|
docPresence,
|
|
108
119
|
submitOperation,
|
|
120
|
+
connected,
|
|
109
121
|
};
|
|
110
122
|
};
|
|
@@ -101,6 +101,8 @@ export type VZCodeContextValue = {
|
|
|
101
101
|
null | (() => void)
|
|
102
102
|
>;
|
|
103
103
|
runCodeRef: React.MutableRefObject<null | (() => void)>;
|
|
104
|
+
|
|
105
|
+
connected: boolean;
|
|
104
106
|
};
|
|
105
107
|
|
|
106
108
|
export const VZCodeProvider = ({
|
|
@@ -115,6 +117,7 @@ export const VZCodeProvider = ({
|
|
|
115
117
|
children,
|
|
116
118
|
codeError = null,
|
|
117
119
|
enableManualPretter = true,
|
|
120
|
+
connected,
|
|
118
121
|
}: {
|
|
119
122
|
content: VZCodeContent;
|
|
120
123
|
shareDBDoc: ShareDBDoc<VZCodeContent>;
|
|
@@ -127,6 +130,7 @@ export const VZCodeProvider = ({
|
|
|
127
130
|
children: React.ReactNode;
|
|
128
131
|
codeError?: string | null;
|
|
129
132
|
enableManualPretter?: boolean;
|
|
133
|
+
connected: boolean;
|
|
130
134
|
}) => {
|
|
131
135
|
// Auto-run Pretter after local changes.
|
|
132
136
|
const {
|
|
@@ -315,6 +319,8 @@ export const VZCodeProvider = ({
|
|
|
315
319
|
handleCreateFileClick,
|
|
316
320
|
runPrettierRef,
|
|
317
321
|
runCodeRef,
|
|
322
|
+
|
|
323
|
+
connected,
|
|
318
324
|
};
|
|
319
325
|
|
|
320
326
|
return (
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useContext,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import { Button, Modal, Form } from './bootstrap';
|
|
3
|
-
import { themes } from './themes';
|
|
9
|
+
import { ThemeLabel, themes } from './themes';
|
|
4
10
|
import { VZCodeContext } from './VZCodeContext';
|
|
11
|
+
import { fonts } from './Fonts/fonts';
|
|
12
|
+
|
|
13
|
+
const fontSizes = ['16px', '18px', '20px', '24px'];
|
|
5
14
|
|
|
6
15
|
export const VZSettings = ({
|
|
7
16
|
enableUsernameField = true,
|
|
@@ -18,11 +27,51 @@ export const VZSettings = ({
|
|
|
18
27
|
setUsername,
|
|
19
28
|
} = useContext(VZCodeContext);
|
|
20
29
|
|
|
21
|
-
const handleThemeChange = useCallback(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
const handleThemeChange = useCallback(
|
|
31
|
+
(event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
32
|
+
setTheme(event.target.value as ThemeLabel);
|
|
33
|
+
},
|
|
34
|
+
[],
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Track selected font and font size.
|
|
38
|
+
// TODO store these in local storage
|
|
39
|
+
const [selectedFont, setSelectedFont] =
|
|
40
|
+
useState('Roboto Mono');
|
|
41
|
+
const [selectedFontSize, setSelectedFontSize] =
|
|
42
|
+
useState('16px');
|
|
43
|
+
|
|
44
|
+
// Called when the user selects a different font
|
|
45
|
+
const handleFontChange = useCallback(
|
|
46
|
+
(event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
47
|
+
setSelectedFont(event.target.value);
|
|
48
|
+
},
|
|
49
|
+
[],
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Called when the user selects a different font size
|
|
53
|
+
const handleFontSizeChange = (
|
|
54
|
+
event: React.ChangeEvent<HTMLSelectElement>,
|
|
55
|
+
) => {
|
|
56
|
+
setSelectedFontSize(event.target.value);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
document.body.style.setProperty(
|
|
61
|
+
'--vzcode-font-family',
|
|
62
|
+
selectedFont,
|
|
63
|
+
);
|
|
64
|
+
}, [selectedFont]);
|
|
65
|
+
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
// const fontSize = event.target.value;
|
|
68
|
+
// const root = document.documentElement;
|
|
69
|
+
// root.style.setProperty('--vzcode-font-size', fontSize);
|
|
70
|
+
document.body.style.setProperty(
|
|
71
|
+
'--vzcode-font-size',
|
|
72
|
+
selectedFontSize,
|
|
73
|
+
);
|
|
74
|
+
}, [selectedFontSize]);
|
|
26
75
|
|
|
27
76
|
const usernameRef = useRef<HTMLInputElement>(null);
|
|
28
77
|
|
|
@@ -77,6 +126,46 @@ export const VZSettings = ({
|
|
|
77
126
|
Select a color theme for the editor
|
|
78
127
|
</Form.Text>
|
|
79
128
|
</Form.Group>
|
|
129
|
+
|
|
130
|
+
<Form.Group className="mb-3" controlId="formFork">
|
|
131
|
+
<Form.Label>Font</Form.Label>
|
|
132
|
+
|
|
133
|
+
<select
|
|
134
|
+
className="form-select"
|
|
135
|
+
onChange={handleFontChange}
|
|
136
|
+
value={selectedFont}
|
|
137
|
+
>
|
|
138
|
+
{fonts.map((font) => (
|
|
139
|
+
<option key={font} value={font}>
|
|
140
|
+
{font}
|
|
141
|
+
</option>
|
|
142
|
+
))}
|
|
143
|
+
</select>
|
|
144
|
+
|
|
145
|
+
<Form.Text className="text-muted">
|
|
146
|
+
Select font for the editor
|
|
147
|
+
</Form.Text>
|
|
148
|
+
</Form.Group>
|
|
149
|
+
|
|
150
|
+
<Form.Group className="mb-3" controlId="formFork">
|
|
151
|
+
<Form.Label>Font Size</Form.Label>
|
|
152
|
+
|
|
153
|
+
<select
|
|
154
|
+
className="form-select"
|
|
155
|
+
onChange={handleFontSizeChange}
|
|
156
|
+
value={selectedFontSize}
|
|
157
|
+
>
|
|
158
|
+
{fontSizes.map((size) => (
|
|
159
|
+
<option key={size} value={size}>
|
|
160
|
+
{size}
|
|
161
|
+
</option>
|
|
162
|
+
))}
|
|
163
|
+
</select>
|
|
164
|
+
|
|
165
|
+
<Form.Text className="text-muted">
|
|
166
|
+
Select a font size for the editor
|
|
167
|
+
</Form.Text>
|
|
168
|
+
</Form.Group>
|
|
80
169
|
</Modal.Body>
|
|
81
170
|
<Modal.Footer>
|
|
82
171
|
<Button variant="primary" onClick={closeSettings}>
|
|
@@ -17,7 +17,7 @@ import './styles.scss';
|
|
|
17
17
|
// TODO turn this UI back on when we are actually detecting
|
|
18
18
|
// the connection status.
|
|
19
19
|
// See https://github.com/vizhub-core/vzcode/issues/456
|
|
20
|
-
const enableConnectionStatus =
|
|
20
|
+
const enableConnectionStatus = true;
|
|
21
21
|
|
|
22
22
|
export const VZSidebar = ({
|
|
23
23
|
createFileTooltipText = 'New File',
|
|
@@ -39,6 +39,7 @@ export const VZSidebar = ({
|
|
|
39
39
|
isDirectoryOpen,
|
|
40
40
|
toggleDirectory,
|
|
41
41
|
handleOpenCreateFileModal,
|
|
42
|
+
connected,
|
|
42
43
|
} = useContext(VZCodeContext);
|
|
43
44
|
|
|
44
45
|
const fileTree = useMemo(
|
|
@@ -174,10 +175,13 @@ export const VZSidebar = ({
|
|
|
174
175
|
|
|
175
176
|
{enableConnectionStatus && (
|
|
176
177
|
<div className="connection-status">
|
|
177
|
-
Connection
|
|
178
|
+
{connected ? 'Connected' : 'Connection Lost'}
|
|
178
179
|
<div className="connection">
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
<div
|
|
181
|
+
className={`connection-status-indicator ${
|
|
182
|
+
connected ? 'connected' : 'disconnected'
|
|
183
|
+
}`}
|
|
184
|
+
/>
|
|
181
185
|
</div>
|
|
182
186
|
</div>
|
|
183
187
|
)}
|
|
@@ -131,18 +131,20 @@
|
|
|
131
131
|
display: flex;
|
|
132
132
|
justify-content: space-between;
|
|
133
133
|
padding: 10px;
|
|
134
|
-
|
|
134
|
+
font-size: 12px;
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
.connection-status-indicator {
|
|
137
|
+
width: 16px;
|
|
138
|
+
height: 16px;
|
|
139
|
+
border-radius: 50%;
|
|
140
|
+
|
|
141
|
+
&.connected {
|
|
142
|
+
background-color: var(--vh-color-success-01);
|
|
143
|
+
}
|
|
141
144
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
background-color: #34eb52;
|
|
145
|
+
&.disconnected {
|
|
146
|
+
background-color: var(--vh-color-warning-01);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
147
149
|
}
|
|
148
150
|
}
|
|
@@ -240,6 +240,11 @@ onmessage = async ({ data }) => {
|
|
|
240
240
|
// of type '"test"' can't be used to index type '{}'."
|
|
241
241
|
const LINT_ERROR_CODE_ANY_TYPE_KEYS = 7053;
|
|
242
242
|
|
|
243
|
+
// "Property 'id' does not exist on type { ... }"
|
|
244
|
+
// Happens on objects with dynamic keys.
|
|
245
|
+
// Not valid in TypeScript, but common in JavaScript.
|
|
246
|
+
const LINT_ERROR_CODE_NON_EXISTENT_PROPERTY = 2339;
|
|
247
|
+
|
|
243
248
|
if (debug) {
|
|
244
249
|
console.log(tsErrors);
|
|
245
250
|
}
|
|
@@ -249,7 +254,9 @@ onmessage = async ({ data }) => {
|
|
|
249
254
|
error.code !== LINT_ERROR_CODE_IMPORT &&
|
|
250
255
|
error.code !== LINT_ERROR_CODE_ANY_PARAM &&
|
|
251
256
|
error.code !== LINT_ERROR_CODE_ANY_TYPE &&
|
|
252
|
-
error.code !== LINT_ERROR_CODE_ANY_TYPE_KEYS
|
|
257
|
+
error.code !== LINT_ERROR_CODE_ANY_TYPE_KEYS &&
|
|
258
|
+
error.code !==
|
|
259
|
+
LINT_ERROR_CODE_NON_EXISTENT_PROPERTY,
|
|
253
260
|
);
|
|
254
261
|
}
|
|
255
262
|
tsErrors = convertToCodeMirrorDiagnostic(tsErrors);
|