vzcode 0.88.0 → 1.0.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 +0 -1
- package/dist/assets/{index-DubfLBmh.js → index-C4h28erw.js} +57 -57
- package/dist/assets/index-CWMOj-be.css +1 -0
- package/dist/assets/index-DacyImKg.js +155 -0
- package/dist/assets/{worker-1Ck54dGO.js → worker-BIf7QrAH.js} +19 -19
- package/dist/index.html +2 -2
- package/package.json +47 -27
- package/src/client/Icons/QuestionMarkSVG.tsx +18 -0
- package/src/client/Icons/index.tsx +1 -0
- package/src/client/RunCodeWidget/index.tsx +8 -2
- package/src/client/RunCodeWidget/style.scss +13 -1
- package/src/client/SplitPaneResizeContext.tsx +1 -1
- package/src/client/VZCodeContext.tsx +11 -0
- package/src/client/VZKeyboardShortcutsDoc.tsx +121 -0
- package/src/client/VZLeft.tsx +4 -0
- package/src/client/VZSettings.tsx +23 -43
- package/src/client/VZSidebar/CreateDirModal.tsx +14 -2
- package/src/client/VZSidebar/CreateFileModal.tsx +14 -2
- package/src/client/VZSidebar/index.tsx +49 -37
- package/src/client/index.ts +1 -0
- package/src/client/useActions.ts +16 -0
- package/src/client/vzReducer/createInitialState.ts +1 -0
- package/src/client/vzReducer/index.ts +5 -0
- package/src/client/vzReducer/setIsDocOpenReducer.ts +9 -0
- package/dist/assets/index-9yhZQKtK.css +0 -1
- package/dist/assets/index-Dx3HipqX.js +0 -155
- package/src/client/featureFlags.js +0 -4
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-DacyImKg.js"></script>
|
|
24
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CWMOj-be.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": "1.0.0",
|
|
4
4
|
"description": "Multiplayer code editor system",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -59,6 +59,26 @@
|
|
|
59
59
|
{
|
|
60
60
|
"name": "Ethan Nuessle",
|
|
61
61
|
"url": "https://github.com/enuessle"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "Brandon Balchand",
|
|
65
|
+
"url": "https://github.com/MandingoBrandon"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "Demetrius Ho Sang",
|
|
69
|
+
"url": "https://github.com/demhos"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "Jary Chen",
|
|
73
|
+
"url": "https://github.com/CJary"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "Shashank Garg",
|
|
77
|
+
"url": "https://github.com/viratkohli2011"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "Nghia Minh Huynh",
|
|
81
|
+
"url": "https://github.com/NghiaMinhHuynh"
|
|
62
82
|
}
|
|
63
83
|
],
|
|
64
84
|
"license": "MIT",
|
|
@@ -67,15 +87,15 @@
|
|
|
67
87
|
},
|
|
68
88
|
"homepage": "https://github.com/vizhub-core/vzcode#readme",
|
|
69
89
|
"dependencies": {
|
|
70
|
-
"@codemirror/autocomplete": "^6.
|
|
90
|
+
"@codemirror/autocomplete": "^6.16.0",
|
|
71
91
|
"@codemirror/lang-css": "^6.2.1",
|
|
72
|
-
"@codemirror/lang-html": "^6.4.
|
|
92
|
+
"@codemirror/lang-html": "^6.4.9",
|
|
73
93
|
"@codemirror/lang-javascript": "^6.2.2",
|
|
74
94
|
"@codemirror/lang-json": "^6.0.1",
|
|
75
|
-
"@codemirror/lang-markdown": "^6.2.
|
|
95
|
+
"@codemirror/lang-markdown": "^6.2.5",
|
|
76
96
|
"@codemirror/state": "^6.4.1",
|
|
77
97
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
78
|
-
"@codemirror/view": "^6.26.
|
|
98
|
+
"@codemirror/view": "^6.26.3",
|
|
79
99
|
"@lezer/highlight": "^1.2.0",
|
|
80
100
|
"@replit/codemirror-indentation-markers": "^6.5.1",
|
|
81
101
|
"@replit/codemirror-interact": "^6.3.1",
|
|
@@ -83,15 +103,15 @@
|
|
|
83
103
|
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
|
84
104
|
"@teamwork/websocket-json-stream": "^2.0.0",
|
|
85
105
|
"@typescript/vfs": "^1.5.0",
|
|
86
|
-
"@uiw/codemirror-theme-abcdef": "^4.
|
|
87
|
-
"@uiw/codemirror-theme-dracula": "^4.
|
|
88
|
-
"@uiw/codemirror-theme-eclipse": "^4.
|
|
89
|
-
"@uiw/codemirror-theme-github": "^4.
|
|
90
|
-
"@uiw/codemirror-theme-material": "^4.
|
|
91
|
-
"@uiw/codemirror-theme-nord": "^4.
|
|
92
|
-
"@uiw/codemirror-theme-okaidia": "^4.
|
|
93
|
-
"@uiw/codemirror-theme-xcode": "^4.
|
|
94
|
-
"@uiw/codemirror-themes": "^4.
|
|
106
|
+
"@uiw/codemirror-theme-abcdef": "^4.22.0",
|
|
107
|
+
"@uiw/codemirror-theme-dracula": "^4.22.0",
|
|
108
|
+
"@uiw/codemirror-theme-eclipse": "^4.22.0",
|
|
109
|
+
"@uiw/codemirror-theme-github": "^4.22.0",
|
|
110
|
+
"@uiw/codemirror-theme-material": "^4.22.0",
|
|
111
|
+
"@uiw/codemirror-theme-nord": "^4.22.0",
|
|
112
|
+
"@uiw/codemirror-theme-okaidia": "^4.22.0",
|
|
113
|
+
"@uiw/codemirror-theme-xcode": "^4.22.0",
|
|
114
|
+
"@uiw/codemirror-themes": "^4.22.0",
|
|
95
115
|
"body-parser": "^1.20.2",
|
|
96
116
|
"codemirror": "^6.0.1",
|
|
97
117
|
"codemirror-ot": "^4.4.0",
|
|
@@ -104,26 +124,26 @@
|
|
|
104
124
|
"json0-ot-diff": "^1.1.2",
|
|
105
125
|
"ngrok": "^4.3.3",
|
|
106
126
|
"open": "^10.1.0",
|
|
107
|
-
"openai": "^4.
|
|
108
|
-
"prettier-plugin-svelte": "^3.2.
|
|
109
|
-
"react": "^18.
|
|
127
|
+
"openai": "^4.40.0",
|
|
128
|
+
"prettier-plugin-svelte": "^3.2.3",
|
|
129
|
+
"react": "^18.3.1",
|
|
110
130
|
"react-bootstrap": "^2.10.2",
|
|
111
|
-
"react-dom": "^18.
|
|
112
|
-
"react-router-dom": "^6.
|
|
131
|
+
"react-dom": "^18.3.1",
|
|
132
|
+
"react-router-dom": "^6.23.0",
|
|
113
133
|
"sharedb": "^4.1.4",
|
|
114
134
|
"sharedb-client-browser": "^4.5.0",
|
|
115
|
-
"vizhub-ui": "^3.
|
|
116
|
-
"ws": "^8.
|
|
135
|
+
"vizhub-ui": "^3.23.0",
|
|
136
|
+
"ws": "^8.17.0"
|
|
117
137
|
},
|
|
118
138
|
"devDependencies": {
|
|
119
|
-
"@types/react": "^18.
|
|
120
|
-
"@types/react-dom": "^18.
|
|
139
|
+
"@types/react": "^18.3.1",
|
|
140
|
+
"@types/react-dom": "^18.3.0",
|
|
121
141
|
"@vitejs/plugin-react": "^4.2.1",
|
|
122
142
|
"concurrently": "^8.2.2",
|
|
123
143
|
"prettier": "^3.2.5",
|
|
124
|
-
"sass": "^1.
|
|
125
|
-
"typescript": "^5.4.
|
|
126
|
-
"vite": "^5.2.
|
|
127
|
-
"vitest": "^1.
|
|
144
|
+
"sass": "^1.76.0",
|
|
145
|
+
"typescript": "^5.4.5",
|
|
146
|
+
"vite": "^5.2.10",
|
|
147
|
+
"vitest": "^1.5.3"
|
|
128
148
|
}
|
|
129
149
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// From https://heroicons.com/
|
|
2
|
+
export const QuestionMarkSVG = () => (
|
|
3
|
+
<svg
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
fill="none"
|
|
6
|
+
width="24"
|
|
7
|
+
height="24"
|
|
8
|
+
viewBox="0 0 24 24"
|
|
9
|
+
strokeWidth="1.5"
|
|
10
|
+
stroke="currentColor"
|
|
11
|
+
>
|
|
12
|
+
<path
|
|
13
|
+
strokeLinecap="round"
|
|
14
|
+
strokeLinejoin="round"
|
|
15
|
+
d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z"
|
|
16
|
+
/>
|
|
17
|
+
</svg>
|
|
18
|
+
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useContext } from 'react';
|
|
1
|
+
import { useCallback, useContext, useState } from 'react';
|
|
2
2
|
import { PlaySVG } from '../Icons';
|
|
3
3
|
import { VZCodeContext } from '../VZCodeContext';
|
|
4
4
|
import { OverlayTrigger, Tooltip } from '../bootstrap';
|
|
@@ -16,8 +16,11 @@ export const RunCodeWidget = ({
|
|
|
16
16
|
}) => {
|
|
17
17
|
const { runCodeRef, runPrettierRef } =
|
|
18
18
|
useContext(VZCodeContext);
|
|
19
|
+
const [isRunning, setIsRunning] = useState(false);
|
|
19
20
|
|
|
20
21
|
const handleClick = useCallback(() => {
|
|
22
|
+
setIsRunning(true); // Set the running state to true
|
|
23
|
+
|
|
21
24
|
// Run Prettier
|
|
22
25
|
const runPrettier = runPrettierRef.current;
|
|
23
26
|
if (runPrettier !== null) {
|
|
@@ -29,6 +32,9 @@ export const RunCodeWidget = ({
|
|
|
29
32
|
if (runCode !== null) {
|
|
30
33
|
runCode();
|
|
31
34
|
}
|
|
35
|
+
|
|
36
|
+
// Optional: reset the icon state after animation completes (e.g., 1 second)
|
|
37
|
+
setTimeout(() => setIsRunning(false), 1000);
|
|
32
38
|
}, []);
|
|
33
39
|
|
|
34
40
|
return (
|
|
@@ -42,7 +48,7 @@ export const RunCodeWidget = ({
|
|
|
42
48
|
}
|
|
43
49
|
>
|
|
44
50
|
<i
|
|
45
|
-
className=
|
|
51
|
+
className={`icon-button icon-button-dark ${isRunning ? 'rotate-icon' : ''}`}
|
|
46
52
|
onClick={handleClick}
|
|
47
53
|
>
|
|
48
54
|
<PlaySVG />
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
position: absolute;
|
|
3
3
|
right: 16px;
|
|
4
4
|
top: 9px;
|
|
5
|
-
// color: var(--vh-color-caution-01);
|
|
6
5
|
color: var(--vh-color-neutral-04);
|
|
6
|
+
|
|
7
|
+
.rotate-icon {
|
|
8
|
+
animation: spin 1s linear;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@keyframes spin {
|
|
13
|
+
from {
|
|
14
|
+
transform: rotate(0deg);
|
|
15
|
+
}
|
|
16
|
+
to {
|
|
17
|
+
transform: rotate(360deg);
|
|
18
|
+
}
|
|
7
19
|
}
|
|
@@ -30,7 +30,7 @@ const localStorageWriteDebounceMS = 800;
|
|
|
30
30
|
const sidebarWidthProperty = 'vzCodeSidebarWidth';
|
|
31
31
|
const codeEditorWidthProperty = 'vzCodeCodeEditorWidth';
|
|
32
32
|
|
|
33
|
-
const initialSidebarWidthDefault =
|
|
33
|
+
const initialSidebarWidthDefault = 250;
|
|
34
34
|
let initialSidebarWidth: number =
|
|
35
35
|
initialSidebarWidthDefault;
|
|
36
36
|
|
|
@@ -87,6 +87,10 @@ export type VZCodeContextValue = {
|
|
|
87
87
|
setIsSettingsOpen: (isSettingsOpen: boolean) => void;
|
|
88
88
|
closeSettings: () => void;
|
|
89
89
|
|
|
90
|
+
isDocOpen: boolean;
|
|
91
|
+
setIsDocOpen: (isDocOpen: boolean) => void;
|
|
92
|
+
closeDoc: () => void;
|
|
93
|
+
|
|
90
94
|
theme: ThemeLabel;
|
|
91
95
|
setTheme: (theme: ThemeLabel) => void;
|
|
92
96
|
|
|
@@ -204,6 +208,7 @@ export const VZCodeProvider = ({
|
|
|
204
208
|
activeFileId,
|
|
205
209
|
theme,
|
|
206
210
|
isSettingsOpen,
|
|
211
|
+
isDocOpen,
|
|
207
212
|
editorWantsFocus,
|
|
208
213
|
username,
|
|
209
214
|
} = state;
|
|
@@ -217,7 +222,9 @@ export const VZCodeProvider = ({
|
|
|
217
222
|
closeTabs,
|
|
218
223
|
setTheme,
|
|
219
224
|
setIsSettingsOpen,
|
|
225
|
+
setIsDocOpen,
|
|
220
226
|
closeSettings,
|
|
227
|
+
closeDoc,
|
|
221
228
|
editorNoLongerWantsFocus,
|
|
222
229
|
setUsername,
|
|
223
230
|
} = useActions(dispatch);
|
|
@@ -344,6 +351,10 @@ export const VZCodeProvider = ({
|
|
|
344
351
|
setIsSettingsOpen,
|
|
345
352
|
closeSettings,
|
|
346
353
|
|
|
354
|
+
isDocOpen,
|
|
355
|
+
setIsDocOpen,
|
|
356
|
+
closeDoc,
|
|
357
|
+
|
|
347
358
|
theme,
|
|
348
359
|
setTheme,
|
|
349
360
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React, { useCallback, useContext } from 'react';
|
|
2
|
+
import { Button, Modal, Form } from './bootstrap';
|
|
3
|
+
import { ThemeLabel, themes } from './themes';
|
|
4
|
+
import { VZCodeContext } from './VZCodeContext';
|
|
5
|
+
|
|
6
|
+
export const VZKeyboardShortcutsDoc = ({
|
|
7
|
+
enableUsernameField = true,
|
|
8
|
+
}: {
|
|
9
|
+
// Feature flag to enable/disable username field
|
|
10
|
+
enableUsernameField?: boolean;
|
|
11
|
+
}) => {
|
|
12
|
+
const {
|
|
13
|
+
isDocOpen,
|
|
14
|
+
closeDoc,
|
|
15
|
+
|
|
16
|
+
setTheme,
|
|
17
|
+
|
|
18
|
+
setUsername,
|
|
19
|
+
} = useContext(VZCodeContext);
|
|
20
|
+
|
|
21
|
+
const handleThemeChange = useCallback(
|
|
22
|
+
(event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
23
|
+
setTheme(event.target.value as ThemeLabel);
|
|
24
|
+
},
|
|
25
|
+
[],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
return isDocOpen ? (
|
|
29
|
+
<Modal
|
|
30
|
+
className="vz-settings"
|
|
31
|
+
show={isDocOpen}
|
|
32
|
+
onHide={closeDoc}
|
|
33
|
+
animation={false}
|
|
34
|
+
>
|
|
35
|
+
<Modal.Header closeButton>
|
|
36
|
+
<Modal.Title>Keyboard Shortcuts</Modal.Title>
|
|
37
|
+
</Modal.Header>
|
|
38
|
+
<Modal.Body className="pt-1">
|
|
39
|
+
<Form.Group className="mb-3">
|
|
40
|
+
<Form.Text className="text-muted">
|
|
41
|
+
Keyboard shortcuts and interactive widgets for
|
|
42
|
+
quick actions
|
|
43
|
+
</Form.Text>
|
|
44
|
+
</Form.Group>
|
|
45
|
+
<Form.Group>
|
|
46
|
+
{/* <Form.Label>WINDOWS</Form.Label> */}
|
|
47
|
+
<ul>
|
|
48
|
+
<li>
|
|
49
|
+
<strong>Ctrl + s</strong> or{' '}
|
|
50
|
+
<strong>Shift + Enter</strong> <br />
|
|
51
|
+
<span>Run and format code</span>
|
|
52
|
+
</li>
|
|
53
|
+
<li>
|
|
54
|
+
<strong>Alt + drag on a number</strong>
|
|
55
|
+
<br />
|
|
56
|
+
<span>
|
|
57
|
+
Modify the number by dragging left or right
|
|
58
|
+
</span>
|
|
59
|
+
</li>
|
|
60
|
+
<li>
|
|
61
|
+
<strong>Alt + click on a hex color</strong>
|
|
62
|
+
<br />
|
|
63
|
+
<span>
|
|
64
|
+
Open a color picker to modify the color
|
|
65
|
+
</span>
|
|
66
|
+
</li>
|
|
67
|
+
<li>
|
|
68
|
+
<strong>Alt + w</strong> <br />
|
|
69
|
+
<span>Close the current tab</span>
|
|
70
|
+
</li>
|
|
71
|
+
<li>
|
|
72
|
+
<strong>Alt + n</strong> <br />
|
|
73
|
+
<span>Open the create file modal</span>
|
|
74
|
+
</li>
|
|
75
|
+
<li>
|
|
76
|
+
<strong>Alt + Page Up</strong> <br />
|
|
77
|
+
<span>
|
|
78
|
+
Change the active tab to the previous one
|
|
79
|
+
</span>
|
|
80
|
+
</li>
|
|
81
|
+
<li>
|
|
82
|
+
<strong>Alt + Page Down</strong> <br />
|
|
83
|
+
<span>
|
|
84
|
+
Change the active tab to the next one
|
|
85
|
+
</span>
|
|
86
|
+
</li>
|
|
87
|
+
<li>
|
|
88
|
+
<strong>Most VSCode Shortcuts</strong> <br />
|
|
89
|
+
See VSCode docs:{' '}
|
|
90
|
+
<a
|
|
91
|
+
href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf"
|
|
92
|
+
target="_blank"
|
|
93
|
+
>
|
|
94
|
+
Windows
|
|
95
|
+
</a>
|
|
96
|
+
,{' '}
|
|
97
|
+
<a
|
|
98
|
+
href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf"
|
|
99
|
+
target="_blank"
|
|
100
|
+
>
|
|
101
|
+
MacOS
|
|
102
|
+
</a>
|
|
103
|
+
,{' '}
|
|
104
|
+
<a
|
|
105
|
+
href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf"
|
|
106
|
+
target="_blank"
|
|
107
|
+
>
|
|
108
|
+
Linux
|
|
109
|
+
</a>
|
|
110
|
+
</li>
|
|
111
|
+
</ul>
|
|
112
|
+
</Form.Group>
|
|
113
|
+
</Modal.Body>
|
|
114
|
+
<Modal.Footer>
|
|
115
|
+
<Button variant="primary" onClick={closeDoc}>
|
|
116
|
+
Done
|
|
117
|
+
</Button>
|
|
118
|
+
</Modal.Footer>
|
|
119
|
+
</Modal>
|
|
120
|
+
) : null;
|
|
121
|
+
};
|
package/src/client/VZLeft.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { VZSettings } from './VZSettings';
|
|
2
|
+
import { VZKeyboardShortcutsDoc } from './VZKeyboardShortcutsDoc';
|
|
2
3
|
import { VZSidebar } from './VZSidebar';
|
|
3
4
|
import { CreateFileModal } from './VZSidebar/CreateFileModal';
|
|
4
5
|
import { CreateDirModal } from './VZSidebar/CreateDirModal';
|
|
@@ -14,6 +15,9 @@ export const VZLeft = ({ enableUsernameField = true }) => {
|
|
|
14
15
|
<VZSettings
|
|
15
16
|
enableUsernameField={enableUsernameField}
|
|
16
17
|
/>
|
|
18
|
+
<VZKeyboardShortcutsDoc
|
|
19
|
+
enableUsernameField={enableUsernameField}
|
|
20
|
+
/>
|
|
17
21
|
<CreateFileModal />
|
|
18
22
|
<CreateDirModal />
|
|
19
23
|
</div>
|
|
@@ -116,6 +116,25 @@ export const VZSettings = ({
|
|
|
116
116
|
setUsername(usernameRef.current?.value || '');
|
|
117
117
|
}, [setUsername]);
|
|
118
118
|
|
|
119
|
+
// Function to handle pressing Enter key
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
if (isSettingsOpen) {
|
|
122
|
+
const handleEnterKey = (event: KeyboardEvent) => {
|
|
123
|
+
if (event.key === 'Enter') {
|
|
124
|
+
closeSettings();
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
window.addEventListener('keydown', handleEnterKey);
|
|
129
|
+
return () => {
|
|
130
|
+
window.removeEventListener(
|
|
131
|
+
'keydown',
|
|
132
|
+
handleEnterKey,
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}, [isSettingsOpen, closeSettings]);
|
|
137
|
+
|
|
119
138
|
return isSettingsOpen ? (
|
|
120
139
|
<Modal
|
|
121
140
|
className="vz-settings"
|
|
@@ -164,6 +183,7 @@ export const VZSettings = ({
|
|
|
164
183
|
|
|
165
184
|
<Form.Group className="mb-3" controlId="formFork">
|
|
166
185
|
<Form.Label>Font</Form.Label>
|
|
186
|
+
|
|
167
187
|
<select
|
|
168
188
|
className="form-select"
|
|
169
189
|
onChange={handleFontChange}
|
|
@@ -175,6 +195,7 @@ export const VZSettings = ({
|
|
|
175
195
|
</option>
|
|
176
196
|
))}
|
|
177
197
|
</select>
|
|
198
|
+
|
|
178
199
|
<Form.Text className="text-muted">
|
|
179
200
|
Select font for the editor
|
|
180
201
|
</Form.Text>
|
|
@@ -182,6 +203,7 @@ export const VZSettings = ({
|
|
|
182
203
|
|
|
183
204
|
<Form.Group className="mb-3" controlId="formFork">
|
|
184
205
|
<Form.Label>Font Size</Form.Label>
|
|
206
|
+
|
|
185
207
|
<select
|
|
186
208
|
className="form-select"
|
|
187
209
|
onChange={handleFontSizeChange}
|
|
@@ -193,51 +215,9 @@ export const VZSettings = ({
|
|
|
193
215
|
</option>
|
|
194
216
|
))}
|
|
195
217
|
</select>
|
|
196
|
-
<Form.Text className="text-muted">
|
|
197
|
-
Select a font size for the editor
|
|
198
|
-
</Form.Text>
|
|
199
|
-
</Form.Group>
|
|
200
218
|
|
|
201
|
-
{/* Keyboard Shortcuts Documentation */}
|
|
202
|
-
<Form.Group className="mb-3" controlId="formFork">
|
|
203
|
-
<Form.Label>Keyboard Shortcuts</Form.Label>
|
|
204
|
-
<ul>
|
|
205
|
-
<li>
|
|
206
|
-
<strong>Alt-w</strong> <span>⌥W</span>
|
|
207
|
-
<br />
|
|
208
|
-
<span>Close the current tab</span>
|
|
209
|
-
</li>
|
|
210
|
-
<li>
|
|
211
|
-
<strong>Alt-n</strong> <span>⌥N</span>
|
|
212
|
-
<br />
|
|
213
|
-
<span>Open the create file modal</span>
|
|
214
|
-
</li>
|
|
215
|
-
<li>
|
|
216
|
-
<strong>Alt-PageUp</strong> <span>⌥⇞</span>
|
|
217
|
-
<br />
|
|
218
|
-
<span>
|
|
219
|
-
Change the active tab to the previous one
|
|
220
|
-
</span>
|
|
221
|
-
</li>
|
|
222
|
-
<li>
|
|
223
|
-
<strong>Alt-PageDown</strong> <span>⌥⇟</span>
|
|
224
|
-
<br />
|
|
225
|
-
<span>
|
|
226
|
-
Change the active tab to the next one
|
|
227
|
-
</span>
|
|
228
|
-
</li>
|
|
229
|
-
<li>
|
|
230
|
-
<strong>Ctrl-s</strong> or{' '}
|
|
231
|
-
<strong>Shift-Enter</strong> <span>⌘S</span>{' '}
|
|
232
|
-
or <span>⇧↩</span>
|
|
233
|
-
<br />
|
|
234
|
-
<span>
|
|
235
|
-
Run the code and format it with Prettier
|
|
236
|
-
</span>
|
|
237
|
-
</li>
|
|
238
|
-
</ul>
|
|
239
219
|
<Form.Text className="text-muted">
|
|
240
|
-
|
|
220
|
+
Select a font size for the editor
|
|
241
221
|
</Form.Text>
|
|
242
222
|
</Form.Group>
|
|
243
223
|
</Modal.Body>
|
|
@@ -15,6 +15,7 @@ export const CreateDirModal = ({
|
|
|
15
15
|
const inputRef = useRef(null);
|
|
16
16
|
|
|
17
17
|
const {
|
|
18
|
+
files,
|
|
18
19
|
isCreateDirModalOpen,
|
|
19
20
|
handleCloseCreateDirModal,
|
|
20
21
|
handleCreateDirClick,
|
|
@@ -38,11 +39,22 @@ export const CreateDirModal = ({
|
|
|
38
39
|
// Returns true if file name is valid, false otherwise.
|
|
39
40
|
const validateFileName = useCallback(
|
|
40
41
|
(fileName: string) => {
|
|
42
|
+
let valid;
|
|
43
|
+
//General Character Check
|
|
41
44
|
const regex =
|
|
42
45
|
/^[a-zA-Z0-9](?:[a-zA-Z0-9 ./+=_-]*[a-zA-Z0-9])?$/;
|
|
43
|
-
|
|
46
|
+
valid = regex.test(fileName);
|
|
47
|
+
|
|
48
|
+
//Check for Duplicate Filename
|
|
49
|
+
for (const key in files) {
|
|
50
|
+
if (fileName + '/' === files[key].name) {
|
|
51
|
+
valid = false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return valid;
|
|
44
56
|
},
|
|
45
|
-
[],
|
|
57
|
+
[files],
|
|
46
58
|
);
|
|
47
59
|
|
|
48
60
|
const handleKeyDown = useCallback(
|
|
@@ -15,6 +15,7 @@ export const CreateFileModal = ({
|
|
|
15
15
|
const inputRef = useRef(null);
|
|
16
16
|
|
|
17
17
|
const {
|
|
18
|
+
files,
|
|
18
19
|
isCreateFileModalOpen,
|
|
19
20
|
handleCloseCreateFileModal,
|
|
20
21
|
handleCreateFileClick,
|
|
@@ -38,11 +39,22 @@ export const CreateFileModal = ({
|
|
|
38
39
|
// Returns true if file name is valid, false otherwise.
|
|
39
40
|
const validateFileName = useCallback(
|
|
40
41
|
(fileName: string) => {
|
|
42
|
+
let valid;
|
|
43
|
+
//General Character Check
|
|
41
44
|
const regex =
|
|
42
45
|
/^[a-zA-Z0-9](?:[a-zA-Z0-9 ./+=_-]*[a-zA-Z0-9])?$/;
|
|
43
|
-
|
|
46
|
+
valid = regex.test(fileName);
|
|
47
|
+
|
|
48
|
+
//Check for Duplicate Filename
|
|
49
|
+
for (const key in files) {
|
|
50
|
+
if (fileName === files[key].name) {
|
|
51
|
+
valid = false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return valid;
|
|
44
56
|
},
|
|
45
|
-
[],
|
|
57
|
+
[files],
|
|
46
58
|
);
|
|
47
59
|
|
|
48
60
|
const handleKeyDown = useCallback(
|