vzcode 0.25.0 → 0.27.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.
Files changed (55) hide show
  1. package/dist/assets/index-5f9f376e.css +1 -0
  2. package/dist/assets/index-70b6d947.js +111 -0
  3. package/dist/index.html +2 -6
  4. package/package.json +7 -7
  5. package/src/client/App.tsx +110 -247
  6. package/src/client/CodeEditor/getOrCreateEditor.ts +6 -1
  7. package/src/client/CodeEditor/index.tsx +94 -16
  8. package/src/client/CodeEditor/{json1PresenceBroadcast.js → json1PresenceBroadcast.ts} +9 -3
  9. package/src/client/CodeEditor/{json1PresenceDisplay.js → json1PresenceDisplay.ts} +9 -48
  10. package/src/client/CodeEditor/style.scss +5 -1
  11. package/src/client/CodeErrorOverlay/index.tsx +27 -0
  12. package/src/client/CodeErrorOverlay/style.scss +30 -0
  13. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +134 -0
  14. package/src/client/PresenceNotifications/index.tsx +119 -106
  15. package/src/client/SplitPaneResizeContext.tsx +12 -7
  16. package/src/client/TabList/Tab.tsx +70 -0
  17. package/src/client/TabList/index.tsx +28 -69
  18. package/src/client/TabList/style.scss +26 -9
  19. package/src/client/{Settings.tsx → VZSettings.tsx} +34 -21
  20. package/src/client/{Sidebar/ConfirmationBox.tsx → VZSidebar/DeleteConfirmationModal.tsx} +17 -14
  21. package/src/client/{Sidebar → VZSidebar}/DirectoryListing.tsx +27 -26
  22. package/src/client/{Sidebar → VZSidebar}/FileListing.tsx +19 -19
  23. package/src/client/VZSidebar/Item.tsx +179 -0
  24. package/src/client/{Sidebar → VZSidebar}/Listing.tsx +20 -14
  25. package/src/client/{Sidebar → VZSidebar}/index.tsx +48 -30
  26. package/src/client/{Sidebar → VZSidebar}/styles.scss +17 -12
  27. package/src/client/bootstrap.ts +3 -0
  28. package/src/client/style.scss +8 -2
  29. package/src/client/useActions.ts +93 -0
  30. package/src/client/useEditorCache.ts +2 -1
  31. package/src/client/useFileCRUD.ts +103 -0
  32. package/src/client/useOpenDirectories.ts +25 -7
  33. package/src/client/useSubmitOperation.ts +25 -0
  34. package/src/client/usernameLocalStorage.ts +43 -0
  35. package/src/client/vzReducer/closeTabReducer.test.ts +177 -0
  36. package/src/client/vzReducer/closeTabsReducer.ts +68 -0
  37. package/src/client/vzReducer/createInitialState.ts +19 -0
  38. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +9 -0
  39. package/src/client/vzReducer/index.ts +107 -0
  40. package/src/client/vzReducer/openTabReducer.test.ts +110 -0
  41. package/src/client/vzReducer/openTabReducer.ts +57 -0
  42. package/src/client/vzReducer/setActiveFileIdReducer.ts +9 -0
  43. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +9 -0
  44. package/src/client/vzReducer/setThemeReducer.ts +9 -0
  45. package/src/client/vzReducer/setUsernameReducer.ts +9 -0
  46. package/src/index.ts +40 -0
  47. package/src/server/index.js +13 -2
  48. package/src/types.ts +12 -5
  49. package/dist/assets/index-8628ebab.js +0 -111
  50. package/dist/assets/index-cf19de3b.css +0 -1
  51. package/src/client/PrettierErrorOverlay/index.tsx +0 -9
  52. package/src/client/PrettierErrorOverlay/style.scss +0 -9
  53. package/src/client/Sidebar/Item.tsx +0 -130
  54. package/src/client/reducer.ts +0 -119
  55. /package/src/client/{Sidebar → VZSidebar}/DirectoryArrowSVG.jsx +0 -0
@@ -1 +0,0 @@
1
- .vz-code-editor{flex:1;display:flex;font-family:var(--vzcode-font-family);overflow-x:auto}.vz-code-editor .cm-editor{flex:1}.vz-sidebar{height:100%;background:rgb(54,65,89);display:flex;flex-direction:column;justify-content:space-between}.vz-sidebar .full-box{padding:7px;display:flex;flex-direction:row;align-items:center;justify-content:space-between}.vz-sidebar .files{overflow:auto}.vz-sidebar .file-or-directory{display:flex;flex-direction:row;align-items:center;justify-content:space-between;cursor:pointer;margin:0 10px;color:#dbdde1;border-radius:5px}.vz-sidebar .link-name{margin-top:30px;margin-left:10px;color:#9aa0ac;font-size:12px;text-decoration:none}.vz-sidebar .new-btn{justify-content:right;margin-right:10px;cursor:pointer}.vz-sidebar .utils{display:flex}.vz-sidebar .utilities{margin-right:3px}.vz-sidebar .file-or-directory:hover,.vz-sidebar .settings:hover{background-color:#4a5469}.vz-sidebar .name{display:flex;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.vz-sidebar .indentation{margin-left:20px}.vz-sidebar .arrow-wrapper{margin-right:4px}.vz-sidebar .settings{height:30px;color:#dbdde1;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:14px 0;margin:10px;border-radius:5px}.vz-tab-list{display:flex;background-color:#252526;overflow-x:auto}.vz-tab-list .tab{background:rgb(45,45,45);color:#fff;font-family:var(--vzcode-font-family);align-items:center;display:flex;padding-top:2px;padding-left:10px;padding-right:10px;border-top-left-radius:10px;border-top-right-radius:10px;margin-top:5px;margin-left:2px;margin-right:2px;cursor:pointer;white-space:nowrap}.vz-tab-list .tab .tab-close{margin-left:5px}.vz-tab-list .tab .tab-close:hover{border-radius:30%;background-color:#252526}.vz-tab-list .tab.active{background-color:#292c34}.vz-resizer{position:absolute;top:0;left:0;bottom:0}.vz-resizer:hover{cursor:col-resize}.vz-resizer .vz-resizer-thumb{position:absolute;top:0;bottom:0;transition:background-color .15s .25s}.vz-resizer:hover .vz-resizer-thumb{background-color:#0078d4}.vz-notification{position:fixed;display:flex;flex-direction:column;gap:10px;bottom:20px;right:20px;color:#9aa0ac;padding:15px}.vz-notification .vz-notification-item{background-color:#364159;padding:5px;border-radius:5px}:root{--vzcode-font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;--vz-bg-color: rgb( 41, 44, 52 )}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:var(--app-bg-color)}::-webkit-scrollbar-thumb{background:rgb(37,37,38)}::-webkit-scrollbar-thumb:hover{background:#555}html,body,#root,.app{height:100%}.app{background-color:var(--vz-bg-color);font-family:Poppins,sans-serif;display:flex;position:relative}.app .left,.app .right{display:flex;position:relative}.app .right{flex:1;flex-direction:column;min-width:0}.prettier-error-overlay{color:#ff3535;background-color:#0009;position:absolute;bottom:0;left:0;right:0;pointer-events:none}
@@ -1,9 +0,0 @@
1
- import './style.scss';
2
-
3
- export const PrettierErrorOverlay = ({ prettierError }) => {
4
- return prettierError !== null ? (
5
- <pre className="prettier-error-overlay">
6
- {prettierError}
7
- </pre>
8
- ) : null;
9
- };
@@ -1,9 +0,0 @@
1
- .prettier-error-overlay {
2
- color: rgb(255, 53, 53);
3
- background-color: rgba(0, 0, 0, 0.6);
4
- position: absolute;
5
- bottom: 0;
6
- left: 0;
7
- right: 0;
8
- pointer-events: none;
9
- }
@@ -1,130 +0,0 @@
1
- import { useState, useCallback, useMemo } from 'react';
2
- import { ConfirmationBox } from './ConfirmationBox';
3
-
4
- export const Item = ({
5
- name,
6
- children,
7
- handleClick,
8
- handleRenameClick,
9
- handleDeleteClick,
10
- isDir,
11
- }) => {
12
- // Tracks whether the mouse is hovering over the file or directory
13
- const [isHovered, setIsHovered] = useState(false);
14
-
15
- // Tracks whether the file is being renamed (inline text input)
16
- const [isRenaming, setIsRenaming] = useState(false);
17
-
18
- // Tracks the value of the input field when renaming
19
- const [renameValue, setRenameValue] = useState('');
20
-
21
- const onKeyDown = useCallback((event) => {
22
- if (event.key === 'Escape') {
23
- setIsRenaming(false);
24
- } else if (event.key === 'Enter') {
25
- event.target.blur();
26
- }
27
- }, []);
28
-
29
- const onBlur = useCallback(
30
- (event: React.FocusEvent<HTMLInputElement>) => {
31
- if (event.target.value.trim() === '') {
32
- // setEditingValue(value);
33
- console.log('TODO: handle empty rename');
34
- } else {
35
- setIsRenaming(false);
36
- handleRenameClick(event.target.value);
37
- }
38
- },
39
- [handleRenameClick],
40
- );
41
-
42
- const [showModal, setShowModal] = useState(false);
43
-
44
- // Function to open the delete file confirmation modal
45
- const handleModalOpen = useCallback(
46
- (event: React.MouseEvent) => {
47
- event.stopPropagation();
48
- setShowModal(true);
49
- },
50
- [],
51
- );
52
-
53
- // Function to close the modal
54
- const handleModalClose = useCallback(() => {
55
- setShowModal(false);
56
- }, []);
57
-
58
- // Function to handle confirmation on modal
59
- const handleConfirmModal = useCallback(
60
- (event: React.MouseEvent) => {
61
- event.stopPropagation();
62
- setShowModal(false);
63
- handleDeleteClick();
64
- },
65
- [handleDeleteClick],
66
- );
67
-
68
- const handleMouseEnter = useCallback(() => {
69
- setIsHovered(true);
70
- }, []);
71
-
72
- const handleMouseLeave = useCallback(() => {
73
- setIsHovered(false);
74
- }, []);
75
-
76
- const onChange = useCallback(
77
- (event: React.ChangeEvent<HTMLInputElement>) => {
78
- setRenameValue(event.target.value);
79
- },
80
- [],
81
- );
82
-
83
- return (
84
- <div
85
- className="full-box file-or-directory"
86
- onClick={isRenaming ? null : handleClick}
87
- onMouseEnter={handleMouseEnter}
88
- onMouseLeave={handleMouseLeave}
89
- >
90
- <div className="name">
91
- {isRenaming ? (
92
- <input
93
- type="text"
94
- aria-label="Field name"
95
- value={renameValue}
96
- onKeyDown={onKeyDown}
97
- onBlur={onBlur}
98
- onChange={onChange}
99
- />
100
- ) : (
101
- children
102
- )}
103
- </div>
104
- {isHovered ? (
105
- <div className="utils">
106
- <i
107
- className="bx bxs-edit utilities"
108
- style={{ color: '#abdafb' }}
109
- onClick={(event: React.MouseEvent) => {
110
- event.stopPropagation();
111
- setIsRenaming(!isRenaming);
112
- setRenameValue(isDir ? name : children);
113
- }}
114
- ></i>
115
- <i
116
- className="bx bx-trash"
117
- style={{ color: '#eb336c' }}
118
- onClick={handleModalOpen}
119
- ></i>
120
- </div>
121
- ) : null}
122
-
123
- <ConfirmationBox
124
- show={showModal}
125
- onClose={handleModalClose}
126
- onConfirm={handleConfirmModal}
127
- />
128
- </div>
129
- );
130
- };
@@ -1,119 +0,0 @@
1
- import { FileId } from '../types';
2
- import { act } from 'react-dom/test-utils';
3
-
4
- export const reducer = (state, action) => {
5
- switch (action.type) {
6
- // TODO phase this out
7
-
8
- // The ordered list of tabs.
9
- // TODO make this a URL param
10
- case 'set_tab_list': {
11
- return { ...state, tabList: action.tabList };
12
- }
13
- // TODO make this a URL param
14
- case 'set_active_fileId': {
15
- return {
16
- ...state,
17
- activeFileId: action.activeFileId,
18
- };
19
- }
20
- case 'open_tab': {
21
- if (!state.tabList.includes(action.fileId)) {
22
- return {
23
- ...state,
24
- activeFileId: action.fileId,
25
- tabList: [...state.tabList, action.fileId],
26
- };
27
- } else {
28
- return {
29
- ...state,
30
- activeFileId: action.fileId,
31
- };
32
- }
33
- }
34
- case 'close_tab': {
35
- const i = state.tabList.findIndex(
36
- (fileId) => fileId === action.fileIdToRemove,
37
- );
38
- if (i != -1) {
39
- const newTabList = [
40
- ...state.tabList.slice(0, i),
41
- ...state.tabList.slice(i + 1),
42
- ];
43
- if (state.activeFileId === action.fileIdToRemove) {
44
- // set the new active file to the next tab over,
45
- if (newTabList.length > 0) {
46
- return {
47
- ...state,
48
- activeFileId:
49
- i === 0 ? newTabList[i] : newTabList[i - 1],
50
- tabList: newTabList,
51
- };
52
- } else {
53
- // or clear out the active file
54
- // if we've closed the last tab.
55
- return {
56
- ...state,
57
- activeFileId: null,
58
- tabList: newTabList,
59
- };
60
- }
61
- }
62
- return {
63
- ...state,
64
- tabList: newTabList,
65
- };
66
- }
67
- return {
68
- ...state,
69
- };
70
- }
71
- case 'multi_close_tab': {
72
- let newTabList = [...state.tabList]; // Create a copy of the tabList array.
73
- let newActiveFileId: FileId = state.activeFileId;
74
- action.idsToDelete.forEach((id) => {
75
- const i = newTabList.findIndex(
76
- (fileId) => fileId === id,
77
- );
78
- if (i !== -1) {
79
- // Remove the tab from the tab list.
80
- newTabList = [
81
- ...newTabList.slice(0, i),
82
- ...newTabList.slice(i + 1),
83
- ];
84
- // If we are closing the active file,
85
- if (newActiveFileId === id) {
86
- // set the new active file to the next tab over,
87
- if (newTabList.length > 0) {
88
- newActiveFileId =
89
- i === 0 ? newTabList[i] : newTabList[i - 1];
90
- } else {
91
- // or clear out the active file if we've closed the last tab.
92
- newActiveFileId = null;
93
- }
94
- }
95
- }
96
- });
97
- return {
98
- ...state,
99
- tabList: newTabList,
100
- activeFileId: newActiveFileId,
101
- };
102
- }
103
- // The current theme.
104
- // TODO persist this in local storage
105
- case 'set_Theme': {
106
- return {
107
- ...state,
108
- theme: action.themeLabel,
109
- };
110
- }
111
- case 'set_Is_Settings_Open': {
112
- return {
113
- ...state,
114
- isSettingsOpen: action.value,
115
- };
116
- }
117
- }
118
- throw Error('Unknown action: ' + action.type);
119
- };