vzcode 0.80.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.
@@ -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
- // Tracks whether the mouse is hovering over the file or directory
46
- const [isHovered, setIsHovered] = useState(false);
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
- <DeleteConfirmationModal
212
- show={showModal}
213
- onClose={handleModalClose}
214
- onConfirm={handleConfirmModal}
215
- isDirectory={isDirectory}
216
- name={name}
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 { DirectoryListing } from './DirectoryListing';
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
  };
@@ -174,17 +174,10 @@ export const VZSidebar = ({
174
174
  <Listing
175
175
  key={key}
176
176
  entity={entity}
177
- renameFile={renameFile}
178
- deleteFile={deleteFile}
179
- renameDirectory={renameDirectory}
180
- deleteDirectory={deleteDirectory}
181
177
  handleFileClick={handleFileClick}
182
178
  handleFileDoubleClick={
183
179
  handleFileDoubleClick
184
180
  }
185
- isDirectoryOpen={isDirectoryOpen}
186
- toggleDirectory={toggleDirectory}
187
- activeFileId={activeFileId}
188
181
  />
189
182
  );
190
183
  })
@@ -267,7 +267,12 @@ onmessage = async ({ data }) => {
267
267
  // flag or with a '--target' of 'es2015' or higher."
268
268
  const LINT_ERROR_CODE_ITERATED_THROUGH = 2802;
269
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
+
270
274
  if (debug) {
275
+ console.log('tsErrors');
271
276
  console.log(tsErrors);
272
277
  }
273
278
  tsErrors = tsErrors.filter(
@@ -279,7 +284,9 @@ onmessage = async ({ data }) => {
279
284
  error.code !== LINT_ERROR_CODE_ANY_TYPE_KEYS &&
280
285
  error.code !==
281
286
  LINT_ERROR_CODE_NON_EXISTENT_PROPERTY &&
282
- 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,
283
290
  );
284
291
  // }
285
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,