vzcode 0.64.0 → 0.66.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-ozxHHf72.js → index-J9vPrCBY.js} +46 -46
- package/dist/assets/worker-ajCMsicA.js +282 -0
- package/dist/assets/{worker-pDIx6AF9.js → worker-lwRU8zh4.js} +45 -45
- package/dist/index.html +1 -1
- package/package.json +8 -8
- package/src/client/VZCodeContext.tsx +51 -1
- package/src/client/VZLeft.tsx +4 -42
- package/src/client/VZSettings.tsx +16 -55
- package/src/client/VZSidebar/CreateFileModal.tsx +19 -14
- package/src/client/VZSidebar/index.tsx +16 -86
- package/src/client/useActions.ts +10 -0
- package/src/client/useKeyboardShortcuts.ts +47 -0
- package/src/client/usePrettier/worker.ts +15 -10
- package/src/client/useTypeScript/worker.ts +14 -6
- package/src/client/vzReducer/index.ts +12 -0
- package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +47 -0
- package/dist/assets/worker-DzDiglXJ.js +0 -233
package/dist/index.html
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
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-
|
|
23
|
+
<script type="module" crossorigin src="/assets/index-J9vPrCBY.js"></script>
|
|
24
24
|
<link rel="stylesheet" crossorigin href="/assets/index-Bh7FzEWq.css">
|
|
25
25
|
</head>
|
|
26
26
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vzcode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.66.0",
|
|
4
4
|
"description": "Multiplayer code editor system",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dev": "concurrently \"npm run test-interactive\" \"vite\"",
|
|
18
18
|
"build": "vite build",
|
|
19
19
|
"build-release": "vite build --mode release",
|
|
20
|
-
"preview": "vite preview",
|
|
20
|
+
"preview": "concurrently \"npm run test-interactive\" \"vite preview\"",
|
|
21
21
|
"prepublishOnly": "npm run build-release"
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@codemirror/lang-markdown": "^6.2.4",
|
|
72
72
|
"@codemirror/state": "^6.4.0",
|
|
73
73
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
74
|
-
"@codemirror/view": "^6.
|
|
74
|
+
"@codemirror/view": "^6.24.0",
|
|
75
75
|
"@lezer/highlight": "^1.2.0",
|
|
76
76
|
"@replit/codemirror-indentation-markers": "^6.5.0",
|
|
77
77
|
"@replit/codemirror-interact": "^6.3.0",
|
|
@@ -94,16 +94,16 @@
|
|
|
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.3",
|
|
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
102
|
"open": "^10.0.3",
|
|
103
|
-
"openai": "^4.
|
|
104
|
-
"prettier-plugin-svelte": "^3.
|
|
103
|
+
"openai": "^4.28.0",
|
|
104
|
+
"prettier-plugin-svelte": "^3.2.0",
|
|
105
105
|
"react": "^18.2.0",
|
|
106
|
-
"react-bootstrap": "^2.10.
|
|
106
|
+
"react-bootstrap": "^2.10.1",
|
|
107
107
|
"react-dom": "^18.2.0",
|
|
108
108
|
"react-router-dom": "^6.22.0",
|
|
109
109
|
"sharedb": "^4.1.2",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"prettier": "^3.2.5",
|
|
120
120
|
"sass": "^1.70.0",
|
|
121
121
|
"typescript": "^5.3.3",
|
|
122
|
-
"vite": "^5.1.
|
|
122
|
+
"vite": "^5.1.1",
|
|
123
123
|
"vitest": "^1.2.2"
|
|
124
124
|
}
|
|
125
125
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useCallback,
|
|
4
|
+
useReducer,
|
|
5
|
+
useState,
|
|
6
|
+
} from 'react';
|
|
2
7
|
import {
|
|
3
8
|
Files,
|
|
4
9
|
ShareDBDoc,
|
|
@@ -25,6 +30,7 @@ import {
|
|
|
25
30
|
useEditorCache,
|
|
26
31
|
} from './useEditorCache';
|
|
27
32
|
import { useURLSync } from './useURLSync';
|
|
33
|
+
import { useKeyboardShortcuts } from './useKeyboardShortcuts';
|
|
28
34
|
|
|
29
35
|
// This context centralizes all the "smart" logic
|
|
30
36
|
// to do with the application state. This includes
|
|
@@ -51,6 +57,8 @@ export type VZCodeContextValue = {
|
|
|
51
57
|
|
|
52
58
|
activeFileId: string | null;
|
|
53
59
|
setActiveFileId: (fileId: string | null) => void;
|
|
60
|
+
setActiveFileLeft: () => void;
|
|
61
|
+
setActiveFileRight: () => void;
|
|
54
62
|
|
|
55
63
|
tabList: Array<TabState>;
|
|
56
64
|
openTab: ({
|
|
@@ -82,6 +90,11 @@ export type VZCodeContextValue = {
|
|
|
82
90
|
errorMessage: string | null;
|
|
83
91
|
|
|
84
92
|
typeScriptWorker: Worker | null;
|
|
93
|
+
|
|
94
|
+
isCreateFileModalOpen: boolean;
|
|
95
|
+
handleOpenCreateFileModal: () => void;
|
|
96
|
+
handleCloseCreateFileModal: () => void;
|
|
97
|
+
handleCreateFileClick: (newFileName: string) => void;
|
|
85
98
|
};
|
|
86
99
|
|
|
87
100
|
export const VZCodeProvider = ({
|
|
@@ -164,6 +177,8 @@ export const VZCodeProvider = ({
|
|
|
164
177
|
// Functions for dispatching actions to the reducer.
|
|
165
178
|
const {
|
|
166
179
|
setActiveFileId,
|
|
180
|
+
setActiveFileLeft,
|
|
181
|
+
setActiveFileRight,
|
|
167
182
|
openTab,
|
|
168
183
|
closeTabs,
|
|
169
184
|
setTheme,
|
|
@@ -205,6 +220,34 @@ export const VZCodeProvider = ({
|
|
|
205
220
|
openTab,
|
|
206
221
|
});
|
|
207
222
|
|
|
223
|
+
// State to control the create file modal's visibility
|
|
224
|
+
const [isCreateFileModalOpen, setIsCreateFileModalOpen] =
|
|
225
|
+
useState(false);
|
|
226
|
+
|
|
227
|
+
const handleOpenCreateFileModal = useCallback(() => {
|
|
228
|
+
setIsCreateFileModalOpen(true);
|
|
229
|
+
}, []);
|
|
230
|
+
|
|
231
|
+
const handleCloseCreateFileModal = useCallback(() => {
|
|
232
|
+
setIsCreateFileModalOpen(false);
|
|
233
|
+
}, []);
|
|
234
|
+
|
|
235
|
+
const handleCreateFileClick = useCallback(
|
|
236
|
+
(newFileName: string) => {
|
|
237
|
+
createFile(newFileName);
|
|
238
|
+
setIsCreateFileModalOpen(false);
|
|
239
|
+
},
|
|
240
|
+
[createFile, setIsCreateFileModalOpen],
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
useKeyboardShortcuts({
|
|
244
|
+
closeTabs,
|
|
245
|
+
activeFileId,
|
|
246
|
+
handleOpenCreateFileModal,
|
|
247
|
+
setActiveFileLeft,
|
|
248
|
+
setActiveFileRight,
|
|
249
|
+
});
|
|
250
|
+
|
|
208
251
|
// Isolate the files object from the document.
|
|
209
252
|
const files: Files | null = content
|
|
210
253
|
? content.files
|
|
@@ -226,6 +269,8 @@ export const VZCodeProvider = ({
|
|
|
226
269
|
|
|
227
270
|
activeFileId,
|
|
228
271
|
setActiveFileId,
|
|
272
|
+
setActiveFileLeft,
|
|
273
|
+
setActiveFileRight,
|
|
229
274
|
|
|
230
275
|
tabList,
|
|
231
276
|
openTab,
|
|
@@ -251,6 +296,11 @@ export const VZCodeProvider = ({
|
|
|
251
296
|
errorMessage,
|
|
252
297
|
|
|
253
298
|
typeScriptWorker,
|
|
299
|
+
|
|
300
|
+
isCreateFileModalOpen,
|
|
301
|
+
handleOpenCreateFileModal,
|
|
302
|
+
handleCloseCreateFileModal,
|
|
303
|
+
handleCreateFileClick,
|
|
254
304
|
};
|
|
255
305
|
|
|
256
306
|
return (
|
package/src/client/VZLeft.tsx
CHANGED
|
@@ -1,57 +1,19 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
1
|
import { VZSettings } from './VZSettings';
|
|
3
2
|
import { VZSidebar } from './VZSidebar';
|
|
4
|
-
import {
|
|
3
|
+
import { CreateFileModal } from './VZSidebar/CreateFileModal';
|
|
5
4
|
|
|
6
5
|
// The middle portion of the VZCode environment, containing:
|
|
7
6
|
// * The sidebar
|
|
8
7
|
// * The settings modal
|
|
8
|
+
// * The create file modal
|
|
9
9
|
export const VZLeft = ({ enableUsernameField = true }) => {
|
|
10
|
-
// TODO leverage this context in deeper levels of the component tree.
|
|
11
|
-
const {
|
|
12
|
-
files,
|
|
13
|
-
createFile,
|
|
14
|
-
renameFile,
|
|
15
|
-
deleteFile,
|
|
16
|
-
deleteDirectory,
|
|
17
|
-
activeFileId,
|
|
18
|
-
openTab,
|
|
19
|
-
closeTabs,
|
|
20
|
-
isSettingsOpen,
|
|
21
|
-
setIsSettingsOpen,
|
|
22
|
-
closeSettings,
|
|
23
|
-
theme,
|
|
24
|
-
setTheme,
|
|
25
|
-
username,
|
|
26
|
-
setUsername,
|
|
27
|
-
isDirectoryOpen,
|
|
28
|
-
toggleDirectory,
|
|
29
|
-
} = useContext(VZCodeContext);
|
|
30
|
-
|
|
31
10
|
return (
|
|
32
11
|
<div className="left">
|
|
33
|
-
<VZSidebar
|
|
34
|
-
files={files}
|
|
35
|
-
createFile={createFile}
|
|
36
|
-
renameFile={renameFile}
|
|
37
|
-
deleteFile={deleteFile}
|
|
38
|
-
deleteDirectory={deleteDirectory}
|
|
39
|
-
openTab={openTab}
|
|
40
|
-
closeTabs={closeTabs}
|
|
41
|
-
setIsSettingsOpen={setIsSettingsOpen}
|
|
42
|
-
isDirectoryOpen={isDirectoryOpen}
|
|
43
|
-
toggleDirectory={toggleDirectory}
|
|
44
|
-
activeFileId={activeFileId}
|
|
45
|
-
/>
|
|
12
|
+
<VZSidebar />
|
|
46
13
|
<VZSettings
|
|
47
|
-
show={isSettingsOpen}
|
|
48
|
-
onClose={closeSettings}
|
|
49
|
-
theme={theme}
|
|
50
|
-
setTheme={setTheme}
|
|
51
|
-
username={username}
|
|
52
|
-
setUsername={setUsername}
|
|
53
14
|
enableUsernameField={enableUsernameField}
|
|
54
15
|
/>
|
|
16
|
+
<CreateFileModal />
|
|
55
17
|
</div>
|
|
56
18
|
);
|
|
57
19
|
};
|
|
@@ -1,67 +1,40 @@
|
|
|
1
|
-
import { useCallback, useRef } from 'react';
|
|
1
|
+
import { useCallback, useContext, useRef } from 'react';
|
|
2
2
|
import { Button, Modal, Form } from './bootstrap';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
// const saveTimes = [
|
|
7
|
-
// { value: 1, label: '1 second' },
|
|
8
|
-
// { value: 5, label: '5 seconds' },
|
|
9
|
-
// { value: 10, label: '10 seconds' },
|
|
10
|
-
// { value: 30, label: '30 seconds' },
|
|
11
|
-
// ];
|
|
3
|
+
import { themes } from './themes';
|
|
4
|
+
import { VZCodeContext } from './VZCodeContext';
|
|
12
5
|
|
|
13
6
|
export const VZSettings = ({
|
|
14
|
-
show,
|
|
15
|
-
onClose,
|
|
16
|
-
theme,
|
|
17
|
-
setTheme,
|
|
18
|
-
username,
|
|
19
|
-
setUsername,
|
|
20
|
-
|
|
21
7
|
enableUsernameField = true,
|
|
22
8
|
}: {
|
|
23
|
-
show: boolean;
|
|
24
|
-
onClose: () => void;
|
|
25
|
-
theme: ThemeLabel;
|
|
26
|
-
setTheme: (theme: ThemeLabel) => void;
|
|
27
|
-
username: Username;
|
|
28
|
-
setUsername: (username: Username) => void;
|
|
29
|
-
|
|
30
9
|
// Feature flag to enable/disable username field
|
|
31
10
|
enableUsernameField?: boolean;
|
|
32
11
|
}) => {
|
|
12
|
+
const {
|
|
13
|
+
isSettingsOpen,
|
|
14
|
+
closeSettings,
|
|
15
|
+
theme,
|
|
16
|
+
setTheme,
|
|
17
|
+
username,
|
|
18
|
+
setUsername,
|
|
19
|
+
} = useContext(VZCodeContext);
|
|
20
|
+
|
|
33
21
|
const handleThemeChange = useCallback((event) => {
|
|
34
22
|
const selectedValue = event.target.value;
|
|
35
23
|
console.log(selectedValue);
|
|
36
24
|
setTheme(selectedValue);
|
|
37
25
|
}, []);
|
|
38
26
|
|
|
39
|
-
// TODO https://github.com/vizhub-core/vzcode/issues/95
|
|
40
|
-
// const handleSaveTimeChange = useCallback(
|
|
41
|
-
// (selectedOption) => {
|
|
42
|
-
// const time = [{ value: selectedOption.value }];
|
|
43
|
-
// fetch('/saveTime', {
|
|
44
|
-
// method: 'POST',
|
|
45
|
-
// headers: {
|
|
46
|
-
// 'Content-Type': 'application/json',
|
|
47
|
-
// },
|
|
48
|
-
// body: JSON.stringify(time),
|
|
49
|
-
// });
|
|
50
|
-
// },
|
|
51
|
-
// [],
|
|
52
|
-
// );
|
|
53
|
-
|
|
54
27
|
const usernameRef = useRef<HTMLInputElement>(null);
|
|
55
28
|
|
|
56
29
|
const handleUsernameChange = useCallback(() => {
|
|
57
30
|
setUsername(usernameRef.current?.value || '');
|
|
58
31
|
}, [setUsername]);
|
|
59
32
|
|
|
60
|
-
return
|
|
33
|
+
return isSettingsOpen ? (
|
|
61
34
|
<Modal
|
|
62
35
|
className="vz-settings"
|
|
63
|
-
show={
|
|
64
|
-
onHide={
|
|
36
|
+
show={isSettingsOpen}
|
|
37
|
+
onHide={closeSettings}
|
|
65
38
|
animation={false}
|
|
66
39
|
>
|
|
67
40
|
<Modal.Header closeButton>
|
|
@@ -104,21 +77,9 @@ export const VZSettings = ({
|
|
|
104
77
|
Select a color theme for the editor
|
|
105
78
|
</Form.Text>
|
|
106
79
|
</Form.Group>
|
|
107
|
-
{/*
|
|
108
|
-
TODO https://github.com/vizhub-core/vzcode/issues/95
|
|
109
|
-
<Form.Group className="mb-3" controlId="formFork">
|
|
110
|
-
<Form.Label>Auto-Save Time</Form.Label>
|
|
111
|
-
<Select
|
|
112
|
-
options={saveTimes}
|
|
113
|
-
onChange={handleSaveTimeChange}
|
|
114
|
-
/>
|
|
115
|
-
<Form.Text className="text-muted">
|
|
116
|
-
Select an auto save time
|
|
117
|
-
</Form.Text>
|
|
118
|
-
</Form.Group> */}
|
|
119
80
|
</Modal.Body>
|
|
120
81
|
<Modal.Footer>
|
|
121
|
-
<Button variant="primary" onClick={
|
|
82
|
+
<Button variant="primary" onClick={closeSettings}>
|
|
122
83
|
Done
|
|
123
84
|
</Button>
|
|
124
85
|
</Modal.Footer>
|
|
@@ -3,32 +3,37 @@ import {
|
|
|
3
3
|
useCallback,
|
|
4
4
|
useRef,
|
|
5
5
|
useEffect,
|
|
6
|
+
useContext,
|
|
6
7
|
} from 'react';
|
|
7
8
|
import { Modal, Form, Button } from '../bootstrap';
|
|
9
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
8
10
|
|
|
9
11
|
export const CreateFileModal = ({
|
|
10
|
-
show,
|
|
11
|
-
onClose,
|
|
12
|
-
onRename,
|
|
13
12
|
initialFileName = '',
|
|
14
13
|
}) => {
|
|
15
14
|
const [newName, setNewName] = useState(initialFileName);
|
|
16
15
|
const inputRef = useRef(null);
|
|
17
16
|
|
|
17
|
+
const {
|
|
18
|
+
isCreateFileModalOpen,
|
|
19
|
+
handleCloseCreateFileModal,
|
|
20
|
+
handleCreateFileClick,
|
|
21
|
+
} = useContext(VZCodeContext);
|
|
22
|
+
|
|
18
23
|
useEffect(() => {
|
|
19
|
-
if (
|
|
24
|
+
if (isCreateFileModalOpen && inputRef.current) {
|
|
20
25
|
inputRef.current.focus();
|
|
21
26
|
}
|
|
22
|
-
}, [
|
|
27
|
+
}, [isCreateFileModalOpen]);
|
|
23
28
|
|
|
24
29
|
const handleNameChange = useCallback((event) => {
|
|
25
30
|
setNewName(event.target.value);
|
|
26
31
|
}, []);
|
|
27
32
|
|
|
28
|
-
const
|
|
29
|
-
|
|
33
|
+
const onCreateClick = useCallback(() => {
|
|
34
|
+
handleCreateFileClick(newName);
|
|
30
35
|
setNewName('');
|
|
31
|
-
}, [newName,
|
|
36
|
+
}, [newName, handleCreateFileClick]);
|
|
32
37
|
|
|
33
38
|
// Returns true if file name is valid, false otherwise.
|
|
34
39
|
const validateFileName = useCallback(
|
|
@@ -48,16 +53,16 @@ export const CreateFileModal = ({
|
|
|
48
53
|
e.shiftKey ||
|
|
49
54
|
(!e.altKey && !e.metaKey))
|
|
50
55
|
) {
|
|
51
|
-
|
|
56
|
+
onCreateClick();
|
|
52
57
|
}
|
|
53
58
|
},
|
|
54
|
-
[
|
|
59
|
+
[onCreateClick],
|
|
55
60
|
);
|
|
56
61
|
|
|
57
|
-
return
|
|
62
|
+
return isCreateFileModalOpen ? (
|
|
58
63
|
<Modal
|
|
59
|
-
show={
|
|
60
|
-
onHide={
|
|
64
|
+
show={isCreateFileModalOpen}
|
|
65
|
+
onHide={handleCloseCreateFileModal}
|
|
61
66
|
animation={false}
|
|
62
67
|
onKeyDown={handleKeyDown}
|
|
63
68
|
>
|
|
@@ -82,7 +87,7 @@ export const CreateFileModal = ({
|
|
|
82
87
|
<Modal.Footer>
|
|
83
88
|
<Button
|
|
84
89
|
variant="primary"
|
|
85
|
-
onClick={
|
|
90
|
+
onClick={onCreateClick}
|
|
86
91
|
disabled={!validateFileName(newName)}
|
|
87
92
|
>
|
|
88
93
|
Create File
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useCallback,
|
|
3
|
-
useContext,
|
|
4
|
-
useMemo,
|
|
5
|
-
useState,
|
|
6
|
-
useEffect,
|
|
7
|
-
} from 'react';
|
|
1
|
+
import { useCallback, useContext, useMemo } from 'react';
|
|
8
2
|
import {
|
|
9
3
|
FileId,
|
|
10
4
|
FileTree,
|
|
11
5
|
FileTreeFile,
|
|
12
|
-
FileTreePath,
|
|
13
|
-
Files,
|
|
14
6
|
} from '../../types';
|
|
15
7
|
import { Tooltip, OverlayTrigger } from '../bootstrap';
|
|
16
8
|
import { getFileTree } from '../getFileTree';
|
|
@@ -19,7 +11,7 @@ import { disableSettings } from '../featureFlags';
|
|
|
19
11
|
import { SplitPaneResizeContext } from '../SplitPaneResizeContext';
|
|
20
12
|
import { BugSVG, GearSVG, NewSVG } from '../Icons';
|
|
21
13
|
import { Listing } from './Listing';
|
|
22
|
-
import {
|
|
14
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
23
15
|
import './styles.scss';
|
|
24
16
|
|
|
25
17
|
// TODO turn this UI back on when we are actually detecting
|
|
@@ -28,89 +20,32 @@ import './styles.scss';
|
|
|
28
20
|
const enableConnectionStatus = false;
|
|
29
21
|
|
|
30
22
|
export const VZSidebar = ({
|
|
31
|
-
files,
|
|
32
|
-
createFile,
|
|
33
23
|
createFileTooltipText = 'New File',
|
|
34
|
-
renameFile,
|
|
35
|
-
deleteFile,
|
|
36
|
-
deleteDirectory,
|
|
37
|
-
openTab,
|
|
38
|
-
closeTabs,
|
|
39
|
-
setIsSettingsOpen,
|
|
40
|
-
isDirectoryOpen,
|
|
41
|
-
toggleDirectory,
|
|
42
|
-
activeFileId,
|
|
43
24
|
openSettingsTooltipText = 'Open Settings',
|
|
44
25
|
reportBugTooltipText = 'Report Bug',
|
|
45
26
|
}: {
|
|
46
|
-
files: Files;
|
|
47
|
-
createFile: (fileName) => void;
|
|
48
27
|
createFileTooltipText?: string;
|
|
49
|
-
renameFile: (fileId: FileId, newName: string) => void;
|
|
50
|
-
deleteFile: (fileId: FileId) => void;
|
|
51
|
-
deleteDirectory: (path: FileTreePath) => void;
|
|
52
|
-
openTab: ({
|
|
53
|
-
fileId,
|
|
54
|
-
isTransient,
|
|
55
|
-
}: {
|
|
56
|
-
fileId: FileId;
|
|
57
|
-
isTransient?: boolean;
|
|
58
|
-
}) => void;
|
|
59
|
-
closeTabs: (fileIds: FileId[]) => void;
|
|
60
|
-
setIsSettingsOpen: (isSettingsOpen: boolean) => void;
|
|
61
|
-
isDirectoryOpen: (path: string) => boolean;
|
|
62
|
-
toggleDirectory: (path: string) => void;
|
|
63
|
-
activeFileId?: FileId;
|
|
64
28
|
openSettingsTooltipText?: string;
|
|
65
29
|
reportBugTooltipText?: string;
|
|
66
30
|
}) => {
|
|
31
|
+
const {
|
|
32
|
+
files,
|
|
33
|
+
renameFile,
|
|
34
|
+
deleteFile,
|
|
35
|
+
deleteDirectory,
|
|
36
|
+
activeFileId,
|
|
37
|
+
openTab,
|
|
38
|
+
setIsSettingsOpen,
|
|
39
|
+
isDirectoryOpen,
|
|
40
|
+
toggleDirectory,
|
|
41
|
+
handleOpenCreateFileModal,
|
|
42
|
+
} = useContext(VZCodeContext);
|
|
43
|
+
|
|
67
44
|
const fileTree = useMemo(
|
|
68
45
|
() => (files ? sortFileTree(getFileTree(files)) : null),
|
|
69
46
|
[files],
|
|
70
47
|
);
|
|
71
48
|
|
|
72
|
-
const [isModalOpen, setIsModalOpen] = useState(false); // State to control the modal's visibility
|
|
73
|
-
|
|
74
|
-
const handleCreateFile = useCallback(() => {
|
|
75
|
-
setIsModalOpen(true);
|
|
76
|
-
}, [setIsModalOpen]);
|
|
77
|
-
|
|
78
|
-
const handleCloseModal = useCallback(() => {
|
|
79
|
-
setIsModalOpen(false);
|
|
80
|
-
}, [setIsModalOpen]);
|
|
81
|
-
|
|
82
|
-
const handleRename = useCallback(
|
|
83
|
-
(newFileName: string) => {
|
|
84
|
-
createFile(newFileName);
|
|
85
|
-
setIsModalOpen(false);
|
|
86
|
-
},
|
|
87
|
-
[createFile, setIsModalOpen],
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const handleKeyPress = useCallback(
|
|
91
|
-
(event: { altKey: boolean; key: string }) => {
|
|
92
|
-
if (event.altKey == true) {
|
|
93
|
-
if (event.key == 'w') {
|
|
94
|
-
closeTabs([activeFileId]);
|
|
95
|
-
}
|
|
96
|
-
if (event.key == 'n') {
|
|
97
|
-
handleCreateFile();
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
[createFile, closeTabs, activeFileId],
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
document.addEventListener('keydown', handleKeyPress);
|
|
106
|
-
return () => {
|
|
107
|
-
document.removeEventListener(
|
|
108
|
-
'keydown',
|
|
109
|
-
handleKeyPress,
|
|
110
|
-
);
|
|
111
|
-
};
|
|
112
|
-
}, [handleKeyPress]);
|
|
113
|
-
|
|
114
49
|
const handleSettingsClick = useCallback(() => {
|
|
115
50
|
setIsSettingsOpen(true);
|
|
116
51
|
}, []);
|
|
@@ -196,7 +131,7 @@ export const VZSidebar = ({
|
|
|
196
131
|
}
|
|
197
132
|
>
|
|
198
133
|
<i
|
|
199
|
-
onClick={
|
|
134
|
+
onClick={handleOpenCreateFileModal}
|
|
200
135
|
className="icon-button icon-button-dark"
|
|
201
136
|
>
|
|
202
137
|
<NewSVG />
|
|
@@ -246,11 +181,6 @@ export const VZSidebar = ({
|
|
|
246
181
|
</div>
|
|
247
182
|
</div>
|
|
248
183
|
)}
|
|
249
|
-
<CreateFileModal
|
|
250
|
-
show={isModalOpen}
|
|
251
|
-
onClose={handleCloseModal}
|
|
252
|
-
onRename={handleRename}
|
|
253
|
-
/>
|
|
254
184
|
</div>
|
|
255
185
|
);
|
|
256
186
|
};
|
package/src/client/useActions.ts
CHANGED
|
@@ -18,6 +18,14 @@ export const useActions = (
|
|
|
18
18
|
[dispatch],
|
|
19
19
|
);
|
|
20
20
|
|
|
21
|
+
const setActiveFileLeft = useCallback(() => {
|
|
22
|
+
dispatch({ type: 'set_active_file_left' });
|
|
23
|
+
}, [dispatch]);
|
|
24
|
+
|
|
25
|
+
const setActiveFileRight = useCallback(() => {
|
|
26
|
+
dispatch({ type: 'set_active_file_right' });
|
|
27
|
+
}, [dispatch]);
|
|
28
|
+
|
|
21
29
|
const openTab = useCallback(
|
|
22
30
|
(tabState: TabState): void => {
|
|
23
31
|
dispatch({
|
|
@@ -82,6 +90,8 @@ export const useActions = (
|
|
|
82
90
|
|
|
83
91
|
return {
|
|
84
92
|
setActiveFileId,
|
|
93
|
+
setActiveFileLeft,
|
|
94
|
+
setActiveFileRight,
|
|
85
95
|
openTab,
|
|
86
96
|
closeTabs,
|
|
87
97
|
setTheme,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useCallback, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
export const useKeyboardShortcuts = ({
|
|
4
|
+
closeTabs,
|
|
5
|
+
activeFileId,
|
|
6
|
+
handleOpenCreateFileModal,
|
|
7
|
+
setActiveFileLeft,
|
|
8
|
+
setActiveFileRight,
|
|
9
|
+
}) => {
|
|
10
|
+
const handleKeyPress = useCallback(
|
|
11
|
+
(event: KeyboardEvent) => {
|
|
12
|
+
if (event.altKey === true) {
|
|
13
|
+
if (event.key === 'w') {
|
|
14
|
+
closeTabs([activeFileId]);
|
|
15
|
+
}
|
|
16
|
+
if (event.key === 'n') {
|
|
17
|
+
handleOpenCreateFileModal();
|
|
18
|
+
}
|
|
19
|
+
if (event.key === 'PageUp') {
|
|
20
|
+
// Change the active tab to the previous one
|
|
21
|
+
setActiveFileLeft();
|
|
22
|
+
}
|
|
23
|
+
if (event.key === 'PageDown') {
|
|
24
|
+
// Change the active tab to the next one
|
|
25
|
+
setActiveFileRight();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
[
|
|
30
|
+
handleOpenCreateFileModal,
|
|
31
|
+
closeTabs,
|
|
32
|
+
activeFileId,
|
|
33
|
+
setActiveFileLeft,
|
|
34
|
+
setActiveFileRight,
|
|
35
|
+
],
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
document.addEventListener('keydown', handleKeyPress);
|
|
40
|
+
return () => {
|
|
41
|
+
document.removeEventListener(
|
|
42
|
+
'keydown',
|
|
43
|
+
handleKeyPress,
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
}, [handleKeyPress]);
|
|
47
|
+
};
|
|
@@ -5,15 +5,12 @@ import * as prettierPluginHtml from 'prettier/plugins/html';
|
|
|
5
5
|
import * as prettierPluginMarkdown from 'prettier/plugins/markdown';
|
|
6
6
|
import * as prettierPluginCSS from 'prettier/plugins/postcss';
|
|
7
7
|
import * as prettierPluginTypescript from 'prettier/plugins/typescript';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// https://github.com/sveltejs/prettier-plugin-svelte/pull/417
|
|
11
|
-
// import * as prettierPluginSvelte from 'prettier-plugin-svelte/browser';
|
|
8
|
+
import * as prettierPluginSvelte from 'prettier-plugin-svelte/browser';
|
|
9
|
+
|
|
12
10
|
import { FileId } from '../../types';
|
|
13
11
|
|
|
14
|
-
const enableSvelte =
|
|
15
|
-
|
|
16
|
-
// console.log(Buffer);
|
|
12
|
+
const enableSvelte = true;
|
|
13
|
+
|
|
17
14
|
const parsers = {
|
|
18
15
|
js: 'babel',
|
|
19
16
|
jsx: 'babel',
|
|
@@ -30,9 +27,13 @@ const parsers = {
|
|
|
30
27
|
md: 'markdown',
|
|
31
28
|
markdown: 'markdown',
|
|
32
29
|
// '.vue': 'vue',
|
|
33
|
-
svelte: 'svelte',
|
|
34
30
|
};
|
|
35
31
|
|
|
32
|
+
if (enableSvelte) {
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
parsers.svelte = 'svelte';
|
|
35
|
+
}
|
|
36
|
+
|
|
36
37
|
const plugins = [
|
|
37
38
|
prettierPluginBabel,
|
|
38
39
|
prettierPluginEstree,
|
|
@@ -40,10 +41,13 @@ const plugins = [
|
|
|
40
41
|
prettierPluginMarkdown,
|
|
41
42
|
prettierPluginTypescript,
|
|
42
43
|
prettierPluginCSS,
|
|
43
|
-
// TODO bring this back
|
|
44
|
-
// prettierPluginSvelte,
|
|
45
44
|
];
|
|
46
45
|
|
|
46
|
+
if (enableSvelte) {
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
plugins.push(prettierPluginSvelte);
|
|
49
|
+
}
|
|
50
|
+
|
|
47
51
|
onmessage = async ({
|
|
48
52
|
data,
|
|
49
53
|
}: {
|
|
@@ -96,6 +100,7 @@ onmessage = async ({
|
|
|
96
100
|
fileTextPrettified,
|
|
97
101
|
});
|
|
98
102
|
} catch (error) {
|
|
103
|
+
console.error(error);
|
|
99
104
|
postMessage({
|
|
100
105
|
fileId,
|
|
101
106
|
error: error.toString(),
|