vzcode 1.13.0 → 1.15.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-BpeGnq7b.js → index-DbFdL1A1.js} +67 -65
- package/dist/assets/{index-Wxh-Jaj6.css → index-Yz-ZHc0O.css} +1 -1
- package/dist/index.html +2 -2
- package/package.json +5 -5
- package/src/client/AIAssist/AIAssistWidget/index.tsx +14 -7
- package/src/client/CodeEditor/getOrCreateEditor.ts +2 -1
- package/src/client/CodeEditor/index.tsx +1 -1
- package/src/client/VZCodeContext.tsx +21 -0
- package/src/client/VZSidebar/FileListing.tsx +20 -56
- package/src/client/VZSidebar/FileTypeIcon.tsx +49 -0
- package/src/client/VZSidebar/Item.tsx +5 -9
- package/src/client/VZSidebar/Search.tsx +412 -108
- package/src/client/VZSidebar/index.tsx +7 -7
- package/src/client/VZSidebar/styles.scss +36 -21
- package/src/client/useActions.ts +31 -0
- package/src/client/useEditorCache.ts +12 -2
- package/src/client/useKeyboardShortcuts.ts +13 -3
- package/src/client/vzReducer/createInitialState.ts +7 -1
- package/src/client/vzReducer/index.ts +21 -0
- package/src/client/vzReducer/openTabReducer.ts +4 -3
- package/src/client/vzReducer/searchReducer.ts +46 -1
- package/src/client/vzReducer/splitCurrentPaneReducer.ts +2 -7
- package/src/types.ts +2 -0
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-DbFdL1A1.js"></script>
|
|
24
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Yz-ZHc0O.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": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "Multiplayer code editor system",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
"react": "^18.3.1",
|
|
146
146
|
"react-bootstrap": "^2.10.4",
|
|
147
147
|
"react-dom": "^18.3.1",
|
|
148
|
-
"react-router-dom": "^6.
|
|
148
|
+
"react-router-dom": "^6.26.0",
|
|
149
149
|
"sharedb": "^5.0.3",
|
|
150
150
|
"sharedb-client-browser": "^5.0.3",
|
|
151
151
|
"vizhub-ui": "^3.23.0",
|
|
@@ -161,10 +161,10 @@
|
|
|
161
161
|
"sass": "^1.77.8",
|
|
162
162
|
"typescript": "^5.5.4",
|
|
163
163
|
"vite": "^5.3.5",
|
|
164
|
-
"vitest": "^2.0.
|
|
164
|
+
"vitest": "^2.0.5"
|
|
165
165
|
},
|
|
166
166
|
"optionalDependencies": {
|
|
167
|
-
"@rollup/rollup-darwin-arm64": "^4.19.
|
|
168
|
-
"@rollup/rollup-win32-x64-msvc": "^4.19.
|
|
167
|
+
"@rollup/rollup-darwin-arm64": "^4.19.2",
|
|
168
|
+
"@rollup/rollup-win32-x64-msvc": "^4.19.2"
|
|
169
169
|
}
|
|
170
170
|
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import { SparklesSVG } from '../../Icons';
|
|
9
9
|
import { startAIAssist } from '../startAIAssist';
|
|
10
10
|
import { Spinner } from '../Spinner';
|
|
11
|
+
import { editorCacheKey } from '../../useEditorCache';
|
|
11
12
|
import './style.scss';
|
|
12
13
|
|
|
13
14
|
const enableStopGeneration = false;
|
|
@@ -23,8 +24,15 @@ export const AIAssistWidget = ({
|
|
|
23
24
|
aiAssistTooltipText?: string;
|
|
24
25
|
aiAssistClickOverride?: () => void;
|
|
25
26
|
}) => {
|
|
26
|
-
const {
|
|
27
|
-
|
|
27
|
+
const {
|
|
28
|
+
shareDBDoc,
|
|
29
|
+
activeFileId,
|
|
30
|
+
activePaneId,
|
|
31
|
+
tabList,
|
|
32
|
+
editorCache,
|
|
33
|
+
runPrettierRef,
|
|
34
|
+
runCodeRef,
|
|
35
|
+
} = useContext(VZCodeContext);
|
|
28
36
|
|
|
29
37
|
// The stream ID of the most recent request.
|
|
30
38
|
// * If `null`, no request has been made yet.
|
|
@@ -33,9 +41,6 @@ export const AIAssistWidget = ({
|
|
|
33
41
|
const [aiStreamId, setAiStreamId] =
|
|
34
42
|
useState<RequestId | null>(null);
|
|
35
43
|
|
|
36
|
-
const { runPrettierRef, runCodeRef } =
|
|
37
|
-
useContext(VZCodeContext);
|
|
38
|
-
|
|
39
44
|
const handleClick = useCallback(async () => {
|
|
40
45
|
const isCurrentlyGenerationg = aiStreamId !== null;
|
|
41
46
|
if (isCurrentlyGenerationg) {
|
|
@@ -46,7 +51,9 @@ export const AIAssistWidget = ({
|
|
|
46
51
|
|
|
47
52
|
// Wait for generation to finish.
|
|
48
53
|
await startAIAssist({
|
|
49
|
-
view: editorCache.get(
|
|
54
|
+
view: editorCache.get(
|
|
55
|
+
editorCacheKey(activeFileId, activePaneId),
|
|
56
|
+
).editor,
|
|
50
57
|
shareDBDoc,
|
|
51
58
|
fileId: activeFileId,
|
|
52
59
|
tabList,
|
|
@@ -89,7 +96,7 @@ export const AIAssistWidget = ({
|
|
|
89
96
|
: currentAIStreamId,
|
|
90
97
|
);
|
|
91
98
|
}
|
|
92
|
-
}, [activeFileId, aiStreamId]);
|
|
99
|
+
}, [activeFileId, activePaneId, aiStreamId]);
|
|
93
100
|
|
|
94
101
|
const showWidget = enableStopGeneration
|
|
95
102
|
? true
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from './InteractiveWidgets';
|
|
34
34
|
import {
|
|
35
35
|
EditorCache,
|
|
36
|
+
editorCacheKey,
|
|
36
37
|
EditorCacheValue,
|
|
37
38
|
} from '../useEditorCache';
|
|
38
39
|
import { ThemeLabel, themeOptionsByLabel } from '../themes';
|
|
@@ -158,7 +159,7 @@ export const getOrCreateEditor = ({
|
|
|
158
159
|
}): EditorCacheValue => {
|
|
159
160
|
// Cache hit
|
|
160
161
|
|
|
161
|
-
const cacheKey = fileId
|
|
162
|
+
const cacheKey = editorCacheKey(fileId, paneId);
|
|
162
163
|
|
|
163
164
|
if (editorCache.has(cacheKey)) {
|
|
164
165
|
return editorCache.get(cacheKey);
|
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
SearchFileVisibility,
|
|
17
17
|
TabState,
|
|
18
18
|
PresenceIndicator,
|
|
19
|
+
Pane,
|
|
20
|
+
PaneId,
|
|
19
21
|
} from '../types';
|
|
20
22
|
import { usePrettier } from './usePrettier';
|
|
21
23
|
import { useTypeScript } from './useTypeScript';
|
|
@@ -75,6 +77,8 @@ export type VZCodeContextValue = {
|
|
|
75
77
|
setActiveFileLeft: () => void;
|
|
76
78
|
setActiveFileRight: () => void;
|
|
77
79
|
|
|
80
|
+
activePaneId: PaneId;
|
|
81
|
+
|
|
78
82
|
tabList: Array<TabState>;
|
|
79
83
|
openTab: (tabState: TabState) => void;
|
|
80
84
|
closeTabs: (fileIds: string[]) => void;
|
|
@@ -119,6 +123,15 @@ export type VZCodeContextValue = {
|
|
|
119
123
|
id: string,
|
|
120
124
|
visibility: SearchFileVisibility,
|
|
121
125
|
) => void;
|
|
126
|
+
setSearchLineVisibility: (
|
|
127
|
+
files: ShareDBDoc<VZCodeContent>,
|
|
128
|
+
id: string,
|
|
129
|
+
line: number,
|
|
130
|
+
) => void;
|
|
131
|
+
setSearchFocusedIndex: (
|
|
132
|
+
focusedIndex: number,
|
|
133
|
+
childIndex: number,
|
|
134
|
+
) => void;
|
|
122
135
|
toggleSearchFocused: () => void;
|
|
123
136
|
|
|
124
137
|
isCreateFileModalOpen: boolean;
|
|
@@ -235,6 +248,7 @@ export const VZCodeProvider = ({
|
|
|
235
248
|
// console.log('state: ', state);
|
|
236
249
|
const {
|
|
237
250
|
pane,
|
|
251
|
+
activePaneId,
|
|
238
252
|
theme,
|
|
239
253
|
search,
|
|
240
254
|
isSearchOpen,
|
|
@@ -265,6 +279,8 @@ export const VZCodeProvider = ({
|
|
|
265
279
|
setSearch,
|
|
266
280
|
setSearchResults,
|
|
267
281
|
setSearchFileVisibility,
|
|
282
|
+
setSearchLineVisibility,
|
|
283
|
+
setSearchFocusedIndex,
|
|
268
284
|
toggleSearchFocused,
|
|
269
285
|
setIsSettingsOpen,
|
|
270
286
|
setIsDocOpen,
|
|
@@ -359,6 +375,7 @@ export const VZCodeProvider = ({
|
|
|
359
375
|
useKeyboardShortcuts({
|
|
360
376
|
closeTabs,
|
|
361
377
|
activeFileId,
|
|
378
|
+
activePaneId,
|
|
362
379
|
handleOpenCreateFileModal,
|
|
363
380
|
setActiveFileLeft,
|
|
364
381
|
setActiveFileRight,
|
|
@@ -395,6 +412,8 @@ export const VZCodeProvider = ({
|
|
|
395
412
|
setActiveFileLeft,
|
|
396
413
|
setActiveFileRight,
|
|
397
414
|
|
|
415
|
+
activePaneId,
|
|
416
|
+
|
|
398
417
|
tabList,
|
|
399
418
|
openTab,
|
|
400
419
|
closeTabs,
|
|
@@ -405,6 +424,8 @@ export const VZCodeProvider = ({
|
|
|
405
424
|
setSearch,
|
|
406
425
|
setSearchResults,
|
|
407
426
|
setSearchFileVisibility,
|
|
427
|
+
setSearchLineVisibility,
|
|
428
|
+
setSearchFocusedIndex,
|
|
408
429
|
toggleSearchFocused,
|
|
409
430
|
|
|
410
431
|
isSettingsOpen,
|
|
@@ -1,44 +1,25 @@
|
|
|
1
1
|
import { useCallback, useContext } from 'react';
|
|
2
2
|
import { Item } from './Item';
|
|
3
3
|
import { FileId, PresenceIndicator } from '../../types';
|
|
4
|
-
import {
|
|
5
|
-
FileSVG,
|
|
6
|
-
JavaScriptSVG,
|
|
7
|
-
TypeScriptSVG,
|
|
8
|
-
ReactSVG,
|
|
9
|
-
SvelteSVG,
|
|
10
|
-
JsonSVG,
|
|
11
|
-
MarkdownSVG,
|
|
12
|
-
HtmlSVG,
|
|
13
|
-
CssSVG,
|
|
14
|
-
} from '../Icons';
|
|
15
4
|
import { VZCodeContext } from '../VZCodeContext';
|
|
5
|
+
import { FileTypeIcon } from './FileTypeIcon';
|
|
16
6
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return <HtmlSVG />;
|
|
34
|
-
case 'css':
|
|
35
|
-
return <CssSVG />;
|
|
36
|
-
case 'svelte':
|
|
37
|
-
return <SvelteSVG />;
|
|
38
|
-
default:
|
|
39
|
-
return <FileSVG />;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
7
|
+
const PresenceIndicators = ({
|
|
8
|
+
presence,
|
|
9
|
+
}: {
|
|
10
|
+
presence: PresenceIndicator[];
|
|
11
|
+
}) => {
|
|
12
|
+
return (
|
|
13
|
+
<div className="presence-indicators">
|
|
14
|
+
{presence.map((indicator, index) => (
|
|
15
|
+
<div key={index} className="presence-indicator">
|
|
16
|
+
{indicator.username[0]}{' '}
|
|
17
|
+
{/* Display the first letter of the username */}
|
|
18
|
+
</div>
|
|
19
|
+
))}
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
42
23
|
|
|
43
24
|
export const FileListing = ({
|
|
44
25
|
name,
|
|
@@ -87,26 +68,9 @@ export const FileListing = ({
|
|
|
87
68
|
handleRenameClick={handleRenameClick}
|
|
88
69
|
isActive={isActive}
|
|
89
70
|
>
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<div className="presence-indicators">
|
|
94
|
-
{presence.map((indicator, index) => (
|
|
95
|
-
<div
|
|
96
|
-
key={index}
|
|
97
|
-
className="presence-indicator"
|
|
98
|
-
>
|
|
99
|
-
{indicator.username[0]}{' '}
|
|
100
|
-
{/* Display the first letter of the username */}
|
|
101
|
-
</div>
|
|
102
|
-
))}
|
|
103
|
-
</div>
|
|
104
|
-
)}
|
|
105
|
-
<i className="file-icon">
|
|
106
|
-
{getExtensionIcon(name)}
|
|
107
|
-
</i>
|
|
108
|
-
{name}
|
|
109
|
-
</div>
|
|
71
|
+
<PresenceIndicators presence={presence} />
|
|
72
|
+
<FileTypeIcon name={name} />
|
|
73
|
+
{name}
|
|
110
74
|
</Item>
|
|
111
75
|
);
|
|
112
76
|
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
FileSVG,
|
|
4
|
+
JavaScriptSVG,
|
|
5
|
+
TypeScriptSVG,
|
|
6
|
+
ReactSVG,
|
|
7
|
+
SvelteSVG,
|
|
8
|
+
JsonSVG,
|
|
9
|
+
MarkdownSVG,
|
|
10
|
+
HtmlSVG,
|
|
11
|
+
CssSVG,
|
|
12
|
+
} from '../Icons';
|
|
13
|
+
|
|
14
|
+
export function getExtensionIcon(fileName: string) {
|
|
15
|
+
const extension = fileName.split('.');
|
|
16
|
+
|
|
17
|
+
switch (extension[extension.length - 1]) {
|
|
18
|
+
case 'jsx':
|
|
19
|
+
case 'tsx':
|
|
20
|
+
return <ReactSVG />;
|
|
21
|
+
case 'js':
|
|
22
|
+
return <JavaScriptSVG />;
|
|
23
|
+
case 'ts':
|
|
24
|
+
return <TypeScriptSVG />;
|
|
25
|
+
case 'json':
|
|
26
|
+
return <JsonSVG />;
|
|
27
|
+
case 'md':
|
|
28
|
+
return <MarkdownSVG />;
|
|
29
|
+
case 'html':
|
|
30
|
+
return <HtmlSVG />;
|
|
31
|
+
case 'css':
|
|
32
|
+
return <CssSVG />;
|
|
33
|
+
case 'svelte':
|
|
34
|
+
return <SvelteSVG />;
|
|
35
|
+
default:
|
|
36
|
+
return <FileSVG />;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Various neat icons based on the file extension
|
|
41
|
+
export const FileTypeIcon = ({
|
|
42
|
+
name,
|
|
43
|
+
}: {
|
|
44
|
+
name: string;
|
|
45
|
+
}) => (
|
|
46
|
+
<i className="file-icon">
|
|
47
|
+
{useMemo(() => getExtensionIcon(name), [name])}
|
|
48
|
+
</i>
|
|
49
|
+
);
|
|
@@ -5,16 +5,14 @@ import {
|
|
|
5
5
|
useEffect,
|
|
6
6
|
useContext,
|
|
7
7
|
} from 'react';
|
|
8
|
-
import {
|
|
8
|
+
import { ItemId } from '../../types';
|
|
9
|
+
import { EditSVG, TrashSVG } from '../Icons';
|
|
9
10
|
import { Tooltip, OverlayTrigger } from '../bootstrap';
|
|
11
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
12
|
+
import { FileTypeIcon } from './FileTypeIcon';
|
|
10
13
|
|
|
11
14
|
// TODO consider moving this up to a higher level of the component tree
|
|
12
15
|
import { DeleteConfirmationModal } from './DeleteConfirmationModal';
|
|
13
|
-
import { VZCodeContext } from '../VZCodeContext';
|
|
14
|
-
import { ItemId } from '../../types';
|
|
15
|
-
import { getExtensionIcon } from './FileListing';
|
|
16
|
-
import { SplitEditorSVG } from '../Icons/SplitEditorSVG';
|
|
17
|
-
import { SplitPaneResizeProvider } from '../SplitPaneResizeContext';
|
|
18
16
|
|
|
19
17
|
const enableRenameDirectory = true;
|
|
20
18
|
|
|
@@ -169,9 +167,7 @@ export const Item = ({
|
|
|
169
167
|
<div className="name">
|
|
170
168
|
{isRenaming ? (
|
|
171
169
|
<>
|
|
172
|
-
<
|
|
173
|
-
{getExtensionIcon(renameValue)}
|
|
174
|
-
</i>
|
|
170
|
+
<FileTypeIcon name={renameValue} />
|
|
175
171
|
<input
|
|
176
172
|
className="rename-input"
|
|
177
173
|
ref={renameInputRef}
|