vzcode 0.79.0 → 0.81.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-DZXcjW4O.js → index-CnwdGSLW.js} +55 -55
- package/dist/assets/{index-WtPPom-d.css → index-J8-kRnnE.css} +1 -1
- package/dist/assets/{worker-Bp-D5zJz.js → worker-tyOiPqgH.js} +53 -53
- package/dist/index.html +2 -2
- package/package.json +13 -13
- package/src/client/AIAssist/AIAssistWidget/index.tsx +4 -16
- package/src/client/CodeEditor/getOrCreateEditor.ts +6 -1
- package/src/client/CodeEditor/index.tsx +7 -1
- package/src/client/CodeEditor/widgets.ts +173 -167
- package/src/client/TabList/index.tsx +13 -19
- package/src/client/VZCodeContext.tsx +12 -0
- package/src/client/VZMiddle.tsx +7 -29
- package/src/client/VZSidebar/DirectoryListing.tsx +12 -32
- package/src/client/VZSidebar/FileListing.tsx +6 -5
- package/src/client/VZSidebar/Item.tsx +30 -10
- package/src/client/VZSidebar/Listing.tsx +6 -30
- package/src/client/VZSidebar/index.tsx +86 -91
- package/src/client/VZSidebar/styles.scss +10 -18
- package/src/client/useFileCRUD.ts +1 -1
- package/src/client/useTypeScript/worker.ts +11 -1
- package/src/types.ts +5 -1
package/src/client/VZMiddle.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import { PresenceNotifications } from './PresenceNotifications';
|
|
|
7
7
|
import { AIAssistWidget } from './AIAssist/AIAssistWidget';
|
|
8
8
|
import { VZCodeContext } from './VZCodeContext';
|
|
9
9
|
import { RunCodeWidget } from './RunCodeWidget';
|
|
10
|
+
import { InteractRule } from '@replit/codemirror-interact';
|
|
10
11
|
|
|
11
12
|
// The middle portion of the VZCode environment, containing:
|
|
12
13
|
// * The list of tabs at the top
|
|
@@ -20,38 +21,25 @@ export const VZMiddle = ({
|
|
|
20
21
|
aiAssistOptions,
|
|
21
22
|
aiAssistTooltipText,
|
|
22
23
|
aiAssistClickOverride,
|
|
24
|
+
customInteractRules,
|
|
23
25
|
}: {
|
|
24
26
|
enableAIAssist?: boolean;
|
|
25
27
|
aiAssistEndpoint?: string;
|
|
26
28
|
aiAssistOptions?: { [key: string]: string };
|
|
27
29
|
aiAssistTooltipText?: string;
|
|
28
30
|
aiAssistClickOverride?: () => void;
|
|
31
|
+
customInteractRules?: Array<InteractRule>;
|
|
29
32
|
}) => {
|
|
30
33
|
const { codeEditorWidth } = useContext(
|
|
31
34
|
SplitPaneResizeContext,
|
|
32
35
|
);
|
|
33
36
|
|
|
34
|
-
// TODO leverage this context in deeper levels of the component tree.
|
|
35
37
|
const {
|
|
36
38
|
content,
|
|
37
|
-
shareDBDoc,
|
|
38
|
-
submitOperation,
|
|
39
39
|
localPresence,
|
|
40
40
|
docPresence,
|
|
41
|
-
files,
|
|
42
|
-
createFile,
|
|
43
41
|
activeFileId,
|
|
44
|
-
setActiveFileId,
|
|
45
|
-
tabList,
|
|
46
|
-
openTab,
|
|
47
|
-
closeTabs,
|
|
48
|
-
theme,
|
|
49
|
-
username,
|
|
50
|
-
editorCache,
|
|
51
|
-
editorWantsFocus,
|
|
52
|
-
editorNoLongerWantsFocus,
|
|
53
42
|
errorMessage,
|
|
54
|
-
typeScriptWorker,
|
|
55
43
|
} = useContext(VZCodeContext);
|
|
56
44
|
|
|
57
45
|
// This prevents the CodeEditor from rendering
|
|
@@ -66,27 +54,17 @@ export const VZMiddle = ({
|
|
|
66
54
|
className="middle"
|
|
67
55
|
style={{ width: codeEditorWidth + 'px' }}
|
|
68
56
|
>
|
|
69
|
-
<TabList
|
|
70
|
-
files={files}
|
|
71
|
-
tabList={tabList}
|
|
72
|
-
activeFileId={activeFileId}
|
|
73
|
-
setActiveFileId={setActiveFileId}
|
|
74
|
-
openTab={openTab}
|
|
75
|
-
closeTabs={closeTabs}
|
|
76
|
-
createFile={createFile}
|
|
77
|
-
/>
|
|
57
|
+
<TabList />
|
|
78
58
|
{isClient && content && activeFileId && (
|
|
79
|
-
<CodeEditor
|
|
59
|
+
<CodeEditor
|
|
60
|
+
customInteractRules={customInteractRules}
|
|
61
|
+
/>
|
|
80
62
|
)}
|
|
81
63
|
{isClient &&
|
|
82
64
|
enableAIAssist &&
|
|
83
65
|
content &&
|
|
84
66
|
activeFileId ? (
|
|
85
67
|
<AIAssistWidget
|
|
86
|
-
activeFileId={activeFileId}
|
|
87
|
-
shareDBDoc={shareDBDoc}
|
|
88
|
-
editorCache={editorCache}
|
|
89
|
-
tabList={tabList}
|
|
90
68
|
aiAssistEndpoint={aiAssistEndpoint}
|
|
91
69
|
aiAssistOptions={aiAssistOptions}
|
|
92
70
|
aiAssistTooltipText={aiAssistTooltipText}
|
|
@@ -1,44 +1,30 @@
|
|
|
1
|
-
import { useCallback, useMemo } from 'react';
|
|
1
|
+
import { useCallback, useContext, useMemo } from 'react';
|
|
2
|
+
import type { FileTree, FileTreeFile } from '../../types';
|
|
3
|
+
import { DirectoryArrowSVG } from '../Icons';
|
|
4
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
2
5
|
import { Item } from './Item';
|
|
3
6
|
import { Listing } from './Listing';
|
|
4
|
-
import { DirectoryArrowSVG } from '../Icons';
|
|
5
|
-
import type {
|
|
6
|
-
FileTree,
|
|
7
|
-
FileTreeFile,
|
|
8
|
-
FileTreePath,
|
|
9
|
-
} from '../../types';
|
|
10
7
|
|
|
11
8
|
export const DirectoryListing = ({
|
|
12
9
|
name,
|
|
13
10
|
path,
|
|
14
11
|
children,
|
|
15
|
-
renameFile,
|
|
16
|
-
deleteFile,
|
|
17
|
-
renameDirectory,
|
|
18
|
-
deleteDirectory,
|
|
19
12
|
handleFileClick,
|
|
20
13
|
handleFileDoubleClick,
|
|
21
|
-
isDirectoryOpen,
|
|
22
|
-
toggleDirectory,
|
|
23
|
-
activeFileId,
|
|
24
14
|
}: {
|
|
25
15
|
name: string;
|
|
26
16
|
path: string;
|
|
27
17
|
children: Array<FileTree | FileTreeFile>;
|
|
28
|
-
renameFile: (fileId: string, newName: string) => void;
|
|
29
|
-
deleteFile: (fileId: string) => void;
|
|
30
|
-
renameDirectory: (
|
|
31
|
-
path: FileTreePath,
|
|
32
|
-
oldName: string,
|
|
33
|
-
newName: string,
|
|
34
|
-
) => void;
|
|
35
|
-
deleteDirectory: (path: FileTreePath) => void;
|
|
36
18
|
handleFileClick: (fileId: string) => void;
|
|
37
19
|
handleFileDoubleClick: (fileId: string) => void;
|
|
38
|
-
isDirectoryOpen: (path: string) => boolean;
|
|
39
|
-
toggleDirectory: (path: string) => void;
|
|
40
|
-
activeFileId: string;
|
|
41
20
|
}) => {
|
|
21
|
+
const {
|
|
22
|
+
renameDirectory,
|
|
23
|
+
deleteDirectory,
|
|
24
|
+
isDirectoryOpen,
|
|
25
|
+
toggleDirectory,
|
|
26
|
+
} = useContext(VZCodeContext);
|
|
27
|
+
|
|
42
28
|
const handleClick = useCallback(() => {
|
|
43
29
|
toggleDirectory(path);
|
|
44
30
|
}, [toggleDirectory, path]);
|
|
@@ -62,6 +48,7 @@ export const DirectoryListing = ({
|
|
|
62
48
|
return (
|
|
63
49
|
<>
|
|
64
50
|
<Item
|
|
51
|
+
id={path}
|
|
65
52
|
name={name}
|
|
66
53
|
handleClick={handleClick}
|
|
67
54
|
handleDeleteClick={handleDeleteClick}
|
|
@@ -87,17 +74,10 @@ export const DirectoryListing = ({
|
|
|
87
74
|
<Listing
|
|
88
75
|
entity={entity}
|
|
89
76
|
key={fileId || path}
|
|
90
|
-
renameFile={renameFile}
|
|
91
|
-
deleteFile={deleteFile}
|
|
92
|
-
renameDirectory={renameDirectory}
|
|
93
|
-
deleteDirectory={deleteDirectory}
|
|
94
77
|
handleFileClick={handleFileClick}
|
|
95
78
|
handleFileDoubleClick={
|
|
96
79
|
handleFileDoubleClick
|
|
97
80
|
}
|
|
98
|
-
isDirectoryOpen={isDirectoryOpen}
|
|
99
|
-
toggleDirectory={toggleDirectory}
|
|
100
|
-
activeFileId={activeFileId}
|
|
101
81
|
/>
|
|
102
82
|
);
|
|
103
83
|
})}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
1
|
+
import { useCallback, useContext } from 'react';
|
|
2
2
|
import { Item } from './Item';
|
|
3
3
|
import { FileId } from '../../types';
|
|
4
4
|
import { FileSVG } from '../Icons';
|
|
5
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
5
6
|
|
|
6
7
|
export const FileListing = ({
|
|
7
8
|
name,
|
|
8
9
|
fileId,
|
|
9
|
-
renameFile,
|
|
10
|
-
deleteFile,
|
|
11
10
|
handleFileClick,
|
|
12
11
|
handleFileDoubleClick,
|
|
13
12
|
isActive,
|
|
14
13
|
}: {
|
|
15
14
|
name: string;
|
|
16
15
|
fileId: FileId;
|
|
17
|
-
renameFile: (fileId: FileId, newName: string) => void;
|
|
18
|
-
deleteFile: (fileId: FileId) => void;
|
|
19
16
|
handleFileClick: (fileId: FileId) => void;
|
|
20
17
|
handleFileDoubleClick: (fileId: FileId) => void;
|
|
21
18
|
isActive: boolean;
|
|
22
19
|
}) => {
|
|
20
|
+
const { renameFile, deleteFile } =
|
|
21
|
+
useContext(VZCodeContext);
|
|
22
|
+
|
|
23
23
|
const handleClick = useCallback(() => {
|
|
24
24
|
handleFileClick(fileId);
|
|
25
25
|
}, [fileId, handleFileClick]);
|
|
@@ -41,6 +41,7 @@ export const FileListing = ({
|
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
43
|
<Item
|
|
44
|
+
id={fileId}
|
|
44
45
|
name={name}
|
|
45
46
|
handleClick={handleClick}
|
|
46
47
|
handleDoubleClick={handleDoubleClick}
|
|
@@ -3,12 +3,15 @@ import {
|
|
|
3
3
|
useCallback,
|
|
4
4
|
useRef,
|
|
5
5
|
useEffect,
|
|
6
|
+
useContext,
|
|
6
7
|
} from 'react';
|
|
7
8
|
import { EditSVG, FileSVG, TrashSVG } from '../Icons';
|
|
8
9
|
import { Tooltip, OverlayTrigger } from '../bootstrap';
|
|
9
10
|
|
|
10
11
|
// TODO consider moving this up to a higher level of the component tree
|
|
11
12
|
import { DeleteConfirmationModal } from './DeleteConfirmationModal';
|
|
13
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
14
|
+
import { ItemId } from '../../types';
|
|
12
15
|
|
|
13
16
|
// TODO support renaming directories
|
|
14
17
|
// See https://github.com/vizhub-core/vzcode/issues/103
|
|
@@ -16,6 +19,7 @@ const enableRenameDirectory = true;
|
|
|
16
19
|
|
|
17
20
|
// A file or directory in the sidebar.
|
|
18
21
|
export const Item = ({
|
|
22
|
+
id,
|
|
19
23
|
name,
|
|
20
24
|
children,
|
|
21
25
|
handleClick,
|
|
@@ -31,6 +35,7 @@ export const Item = ({
|
|
|
31
35
|
? 'Delete Directory'
|
|
32
36
|
: 'Delete File',
|
|
33
37
|
}: {
|
|
38
|
+
id: ItemId;
|
|
34
39
|
name: string;
|
|
35
40
|
children: React.ReactNode;
|
|
36
41
|
handleClick: (event: React.MouseEvent) => void;
|
|
@@ -42,8 +47,21 @@ export const Item = ({
|
|
|
42
47
|
renameFileTooltipText?: string;
|
|
43
48
|
deleteFileTooltipText?: string;
|
|
44
49
|
}) => {
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
const { hoveredItemId, setHoveredItemId } =
|
|
51
|
+
useContext(VZCodeContext);
|
|
52
|
+
// // Tracks whether the mouse is hovering over the file or directory
|
|
53
|
+
// const [isHovered, setIsHovered] = useState(false);
|
|
54
|
+
const isHovered = hoveredItemId === id;
|
|
55
|
+
const setIsHovered = useCallback(
|
|
56
|
+
(isHovered: boolean) => {
|
|
57
|
+
if (isHovered) {
|
|
58
|
+
setHoveredItemId(id);
|
|
59
|
+
} else {
|
|
60
|
+
setHoveredItemId(null);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
[id, setHoveredItemId],
|
|
64
|
+
);
|
|
47
65
|
|
|
48
66
|
// Tracks whether the file is being renamed (inline text input)
|
|
49
67
|
const [isRenaming, setIsRenaming] = useState(false);
|
|
@@ -207,14 +225,16 @@ export const Item = ({
|
|
|
207
225
|
</OverlayTrigger>
|
|
208
226
|
</div>
|
|
209
227
|
) : null}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
228
|
+
{/* TODO Move this up to a higher level of the tree */}
|
|
229
|
+
{showModal && (
|
|
230
|
+
<DeleteConfirmationModal
|
|
231
|
+
show={showModal}
|
|
232
|
+
onClose={handleModalClose}
|
|
233
|
+
onConfirm={handleConfirmModal}
|
|
234
|
+
isDirectory={isDirectory}
|
|
235
|
+
name={name}
|
|
236
|
+
/>
|
|
237
|
+
)}
|
|
218
238
|
</div>
|
|
219
239
|
);
|
|
220
240
|
};
|
|
@@ -1,49 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import type {
|
|
3
3
|
FileId,
|
|
4
4
|
FileTree,
|
|
5
5
|
FileTreeFile,
|
|
6
|
-
FileTreePath,
|
|
7
6
|
} from '../../types';
|
|
7
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
8
|
+
import { DirectoryListing } from './DirectoryListing';
|
|
8
9
|
import { FileListing } from './FileListing';
|
|
9
10
|
|
|
10
11
|
// A "Listing" is a "FileListing" or a "DirectoryListing"
|
|
11
12
|
// that appears in the Sidebar.
|
|
12
13
|
export const Listing = ({
|
|
13
14
|
entity,
|
|
14
|
-
renameFile,
|
|
15
|
-
deleteFile,
|
|
16
|
-
renameDirectory,
|
|
17
|
-
deleteDirectory,
|
|
18
15
|
handleFileClick,
|
|
19
16
|
handleFileDoubleClick,
|
|
20
|
-
isDirectoryOpen,
|
|
21
|
-
toggleDirectory,
|
|
22
|
-
activeFileId,
|
|
23
17
|
}: {
|
|
24
18
|
entity: FileTree | FileTreeFile;
|
|
25
|
-
renameFile: (fileId: FileId, newName: string) => void;
|
|
26
|
-
deleteFile: (fileId: FileId) => void;
|
|
27
|
-
renameDirectory: (
|
|
28
|
-
path: FileTreePath,
|
|
29
|
-
oldName: string,
|
|
30
|
-
newName: string,
|
|
31
|
-
) => void;
|
|
32
|
-
deleteDirectory: (path: FileTreePath) => void;
|
|
33
19
|
handleFileClick: (fileId: FileId) => void;
|
|
34
20
|
handleFileDoubleClick: (fileId: FileId) => void;
|
|
35
|
-
isDirectoryOpen: (path: string) => boolean;
|
|
36
|
-
toggleDirectory: (path: string) => void;
|
|
37
|
-
activeFileId: FileId;
|
|
38
21
|
}) => {
|
|
22
|
+
const { activeFileId } = useContext(VZCodeContext);
|
|
39
23
|
const { name, file, fileId } = entity as FileTreeFile;
|
|
40
24
|
const { path, children } = entity as FileTree;
|
|
25
|
+
|
|
41
26
|
return file ? (
|
|
42
27
|
<FileListing
|
|
43
28
|
fileId={fileId}
|
|
44
29
|
name={name}
|
|
45
|
-
renameFile={renameFile}
|
|
46
|
-
deleteFile={deleteFile}
|
|
47
30
|
handleFileClick={handleFileClick}
|
|
48
31
|
handleFileDoubleClick={handleFileDoubleClick}
|
|
49
32
|
isActive={fileId === activeFileId}
|
|
@@ -53,15 +36,8 @@ export const Listing = ({
|
|
|
53
36
|
name={name}
|
|
54
37
|
path={path}
|
|
55
38
|
children={children}
|
|
56
|
-
renameFile={renameFile}
|
|
57
|
-
deleteFile={deleteFile}
|
|
58
|
-
renameDirectory={renameDirectory}
|
|
59
|
-
deleteDirectory={deleteDirectory}
|
|
60
39
|
handleFileClick={handleFileClick}
|
|
61
40
|
handleFileDoubleClick={handleFileDoubleClick}
|
|
62
|
-
isDirectoryOpen={isDirectoryOpen}
|
|
63
|
-
toggleDirectory={toggleDirectory}
|
|
64
|
-
activeFileId={activeFileId}
|
|
65
41
|
/>
|
|
66
42
|
);
|
|
67
43
|
};
|
|
@@ -94,121 +94,116 @@ export const VZSidebar = ({
|
|
|
94
94
|
|
|
95
95
|
return (
|
|
96
96
|
<div
|
|
97
|
-
className=
|
|
97
|
+
className="vz-sidebar"
|
|
98
|
+
style={{ width: sidebarWidth + 'px' }}
|
|
98
99
|
onDragEnter={handleDragEnter}
|
|
99
100
|
onDragOver={handleDragOver}
|
|
100
101
|
onDragLeave={handleDragLeave}
|
|
101
102
|
onDrop={handleDrop}
|
|
102
103
|
>
|
|
103
|
-
<div
|
|
104
|
-
className="
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<div className="
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
<div className="files">
|
|
105
|
+
<div className="full-box">
|
|
106
|
+
<div className="sidebar-section-hint">
|
|
107
|
+
Project Files
|
|
108
|
+
</div>
|
|
109
|
+
<div className="sidebar-section-buttons">
|
|
110
|
+
<OverlayTrigger
|
|
111
|
+
placement="left"
|
|
112
|
+
overlay={
|
|
113
|
+
<Tooltip id="report-bug-tooltip">
|
|
114
|
+
{reportBugTooltipText}
|
|
115
|
+
</Tooltip>
|
|
116
|
+
}
|
|
117
|
+
>
|
|
118
|
+
<a
|
|
119
|
+
href="https://github.com/vizhub-core/vzcode/issues/new"
|
|
120
|
+
target="_blank"
|
|
121
|
+
rel="noopener noreferrer"
|
|
120
122
|
>
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<BugSVG />
|
|
128
|
-
</i>
|
|
129
|
-
</a>
|
|
130
|
-
</OverlayTrigger>
|
|
131
|
-
{disableSettings ? null : (
|
|
132
|
-
<OverlayTrigger
|
|
133
|
-
placement="left"
|
|
134
|
-
overlay={
|
|
135
|
-
<Tooltip id="open-settings-tooltip">
|
|
136
|
-
{openSettingsTooltipText}
|
|
137
|
-
</Tooltip>
|
|
138
|
-
}
|
|
139
|
-
>
|
|
140
|
-
<i
|
|
141
|
-
onClick={handleSettingsClick}
|
|
142
|
-
className="icon-button icon-button-dark"
|
|
143
|
-
>
|
|
144
|
-
<GearSVG />
|
|
145
|
-
</i>
|
|
146
|
-
</OverlayTrigger>
|
|
147
|
-
)}
|
|
123
|
+
<i className="icon-button icon-button-dark">
|
|
124
|
+
<BugSVG />
|
|
125
|
+
</i>
|
|
126
|
+
</a>
|
|
127
|
+
</OverlayTrigger>
|
|
128
|
+
{disableSettings ? null : (
|
|
148
129
|
<OverlayTrigger
|
|
149
130
|
placement="left"
|
|
150
131
|
overlay={
|
|
151
|
-
<Tooltip id="
|
|
152
|
-
{
|
|
132
|
+
<Tooltip id="open-settings-tooltip">
|
|
133
|
+
{openSettingsTooltipText}
|
|
153
134
|
</Tooltip>
|
|
154
135
|
}
|
|
155
136
|
>
|
|
156
137
|
<i
|
|
157
|
-
onClick={
|
|
138
|
+
onClick={handleSettingsClick}
|
|
158
139
|
className="icon-button icon-button-dark"
|
|
159
140
|
>
|
|
160
|
-
<
|
|
141
|
+
<GearSVG />
|
|
161
142
|
</i>
|
|
162
143
|
</OverlayTrigger>
|
|
163
|
-
|
|
144
|
+
)}
|
|
145
|
+
<OverlayTrigger
|
|
146
|
+
placement="left"
|
|
147
|
+
overlay={
|
|
148
|
+
<Tooltip id="create-file-tooltip">
|
|
149
|
+
{createFileTooltipText}
|
|
150
|
+
</Tooltip>
|
|
151
|
+
}
|
|
152
|
+
>
|
|
153
|
+
<i
|
|
154
|
+
onClick={handleOpenCreateFileModal}
|
|
155
|
+
className="icon-button icon-button-dark"
|
|
156
|
+
>
|
|
157
|
+
<NewSVG />
|
|
158
|
+
</i>
|
|
159
|
+
</OverlayTrigger>
|
|
164
160
|
</div>
|
|
165
|
-
{filesExist ? (
|
|
166
|
-
fileTree.children.map((entity) => {
|
|
167
|
-
const { fileId } = entity as FileTreeFile;
|
|
168
|
-
const { path } = entity as FileTree;
|
|
169
|
-
const key = fileId ? fileId : path;
|
|
170
|
-
return (
|
|
171
|
-
<Listing
|
|
172
|
-
key={key}
|
|
173
|
-
entity={entity}
|
|
174
|
-
renameFile={renameFile}
|
|
175
|
-
deleteFile={deleteFile}
|
|
176
|
-
renameDirectory={renameDirectory}
|
|
177
|
-
deleteDirectory={deleteDirectory}
|
|
178
|
-
handleFileClick={handleFileClick}
|
|
179
|
-
handleFileDoubleClick={
|
|
180
|
-
handleFileDoubleClick
|
|
181
|
-
}
|
|
182
|
-
isDirectoryOpen={isDirectoryOpen}
|
|
183
|
-
toggleDirectory={toggleDirectory}
|
|
184
|
-
activeFileId={activeFileId}
|
|
185
|
-
/>
|
|
186
|
-
);
|
|
187
|
-
})
|
|
188
|
-
) : (
|
|
189
|
-
<div className="empty">
|
|
190
|
-
<div className="empty-text">
|
|
191
|
-
It looks like you don't have any files yet!
|
|
192
|
-
Click the "Create file" button above to
|
|
193
|
-
create your first file.
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
)}
|
|
197
161
|
</div>
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
162
|
+
{isDragOver ? (
|
|
163
|
+
<div className="empty">
|
|
164
|
+
<div className="empty-text">
|
|
165
|
+
Drop files here!
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
) : filesExist ? (
|
|
169
|
+
fileTree.children.map((entity) => {
|
|
170
|
+
const { fileId } = entity as FileTreeFile;
|
|
171
|
+
const { path } = entity as FileTree;
|
|
172
|
+
const key = fileId ? fileId : path;
|
|
173
|
+
return (
|
|
174
|
+
<Listing
|
|
175
|
+
key={key}
|
|
176
|
+
entity={entity}
|
|
177
|
+
handleFileClick={handleFileClick}
|
|
178
|
+
handleFileDoubleClick={
|
|
179
|
+
handleFileDoubleClick
|
|
180
|
+
}
|
|
207
181
|
/>
|
|
182
|
+
);
|
|
183
|
+
})
|
|
184
|
+
) : (
|
|
185
|
+
<div className="empty">
|
|
186
|
+
<div className="empty-text">
|
|
187
|
+
It looks like you don't have any files yet!
|
|
188
|
+
Click the "Create file" button above to create
|
|
189
|
+
your first file.
|
|
208
190
|
</div>
|
|
209
191
|
</div>
|
|
210
192
|
)}
|
|
211
193
|
</div>
|
|
194
|
+
|
|
195
|
+
{enableConnectionStatus && (
|
|
196
|
+
<div className="connection-status">
|
|
197
|
+
{connected ? 'Connected' : 'Connection Lost'}
|
|
198
|
+
<div className="connection">
|
|
199
|
+
<div
|
|
200
|
+
className={`connection-status-indicator ${
|
|
201
|
+
connected ? 'connected' : 'disconnected'
|
|
202
|
+
}`}
|
|
203
|
+
/>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
)}
|
|
212
207
|
</div>
|
|
213
208
|
);
|
|
214
209
|
};
|
|
@@ -127,11 +127,17 @@
|
|
|
127
127
|
padding: 20px;
|
|
128
128
|
border: 1px dashed rgba(255, 255, 255, 0.5); /* White dashed outline */
|
|
129
129
|
border-radius: 10px;
|
|
130
|
-
}
|
|
131
130
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
/*
|
|
132
|
+
* This fixes some issues where the drop zone for files
|
|
133
|
+
* was flickering when dragging files over the sidebar.
|
|
134
|
+
*/
|
|
135
|
+
pointer-events: none;
|
|
136
|
+
|
|
137
|
+
.empty-text {
|
|
138
|
+
font-size: 16px;
|
|
139
|
+
font-weight: 500;
|
|
140
|
+
}
|
|
135
141
|
}
|
|
136
142
|
|
|
137
143
|
.connection-status {
|
|
@@ -155,17 +161,3 @@
|
|
|
155
161
|
}
|
|
156
162
|
}
|
|
157
163
|
}
|
|
158
|
-
|
|
159
|
-
.drop-zone {
|
|
160
|
-
height: 100%;
|
|
161
|
-
border: 3px solid #0a1731;
|
|
162
|
-
width: auto;
|
|
163
|
-
color: #bdc7dc;
|
|
164
|
-
text-align: center;
|
|
165
|
-
font-family: var(--vzcode-font-family);
|
|
166
|
-
font-weight: 500;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
.drop-zone.dragover {
|
|
170
|
-
border-color: #009639;
|
|
171
|
-
}
|
|
@@ -132,7 +132,7 @@ export const useFileCRUD = ({
|
|
|
132
132
|
submitOperation((document: VZCodeContent) => {
|
|
133
133
|
const updatedFiles = { ...document.files };
|
|
134
134
|
for (const key in updatedFiles) {
|
|
135
|
-
if (updatedFiles[key].name.includes(path)) {
|
|
135
|
+
if (updatedFiles[key].name.includes(path + '/')) {
|
|
136
136
|
tabsToClose.push(key);
|
|
137
137
|
delete updatedFiles[key];
|
|
138
138
|
}
|
|
@@ -53,6 +53,9 @@ const initializeFileSystem = async () => {
|
|
|
53
53
|
|
|
54
54
|
// Skip type checking of declaration files
|
|
55
55
|
skipLibCheck: true,
|
|
56
|
+
|
|
57
|
+
// Support React JSX
|
|
58
|
+
jsx: ts.JsxEmit.React,
|
|
56
59
|
};
|
|
57
60
|
|
|
58
61
|
// `true` breaks in a Web Worker because
|
|
@@ -264,7 +267,12 @@ onmessage = async ({ data }) => {
|
|
|
264
267
|
// flag or with a '--target' of 'es2015' or higher."
|
|
265
268
|
const LINT_ERROR_CODE_ITERATED_THROUGH = 2802;
|
|
266
269
|
|
|
270
|
+
// Argument of type '{ Month: string; High: number; Temp: number; Low: number; }'
|
|
271
|
+
// is not assignable to parameter of type 'never'.
|
|
272
|
+
const LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER = 2345;
|
|
273
|
+
|
|
267
274
|
if (debug) {
|
|
275
|
+
console.log('tsErrors');
|
|
268
276
|
console.log(tsErrors);
|
|
269
277
|
}
|
|
270
278
|
tsErrors = tsErrors.filter(
|
|
@@ -276,7 +284,9 @@ onmessage = async ({ data }) => {
|
|
|
276
284
|
error.code !== LINT_ERROR_CODE_ANY_TYPE_KEYS &&
|
|
277
285
|
error.code !==
|
|
278
286
|
LINT_ERROR_CODE_NON_EXISTENT_PROPERTY &&
|
|
279
|
-
error.code !== LINT_ERROR_CODE_ITERATED_THROUGH
|
|
287
|
+
error.code !== LINT_ERROR_CODE_ITERATED_THROUGH &&
|
|
288
|
+
error.code !==
|
|
289
|
+
LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER,
|
|
280
290
|
);
|
|
281
291
|
// }
|
|
282
292
|
tsErrors = convertToCodeMirrorDiagnostic(tsErrors);
|
package/src/types.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
// FileId
|
|
2
2
|
// * A unique ID for a file.
|
|
3
|
-
|
|
4
3
|
// * This is a random string.
|
|
5
4
|
export type FileId = string;
|
|
6
5
|
|
|
6
|
+
// ItemId
|
|
7
|
+
// * A unique ID for an item in the sidebar.
|
|
8
|
+
// * This could be either a file ID or a directory path.
|
|
9
|
+
export type ItemId = FileId | FileTreePath;
|
|
10
|
+
|
|
7
11
|
// Files
|
|
8
12
|
// * A collection of files.
|
|
9
13
|
// * Keys are _not_ file names or array indices,
|