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.
- package/dist/assets/index-5f9f376e.css +1 -0
- package/dist/assets/index-70b6d947.js +111 -0
- package/dist/index.html +2 -6
- package/package.json +7 -7
- package/src/client/App.tsx +110 -247
- package/src/client/CodeEditor/getOrCreateEditor.ts +6 -1
- package/src/client/CodeEditor/index.tsx +94 -16
- package/src/client/CodeEditor/{json1PresenceBroadcast.js → json1PresenceBroadcast.ts} +9 -3
- package/src/client/CodeEditor/{json1PresenceDisplay.js → json1PresenceDisplay.ts} +9 -48
- package/src/client/CodeEditor/style.scss +5 -1
- package/src/client/CodeErrorOverlay/index.tsx +27 -0
- package/src/client/CodeErrorOverlay/style.scss +30 -0
- package/src/client/PresenceNotifications/PresenceNotifications.test.ts +134 -0
- package/src/client/PresenceNotifications/index.tsx +119 -106
- package/src/client/SplitPaneResizeContext.tsx +12 -7
- package/src/client/TabList/Tab.tsx +70 -0
- package/src/client/TabList/index.tsx +28 -69
- package/src/client/TabList/style.scss +26 -9
- package/src/client/{Settings.tsx → VZSettings.tsx} +34 -21
- package/src/client/{Sidebar/ConfirmationBox.tsx → VZSidebar/DeleteConfirmationModal.tsx} +17 -14
- package/src/client/{Sidebar → VZSidebar}/DirectoryListing.tsx +27 -26
- package/src/client/{Sidebar → VZSidebar}/FileListing.tsx +19 -19
- package/src/client/VZSidebar/Item.tsx +179 -0
- package/src/client/{Sidebar → VZSidebar}/Listing.tsx +20 -14
- package/src/client/{Sidebar → VZSidebar}/index.tsx +48 -30
- package/src/client/{Sidebar → VZSidebar}/styles.scss +17 -12
- package/src/client/bootstrap.ts +3 -0
- package/src/client/style.scss +8 -2
- package/src/client/useActions.ts +93 -0
- package/src/client/useEditorCache.ts +2 -1
- package/src/client/useFileCRUD.ts +103 -0
- package/src/client/useOpenDirectories.ts +25 -7
- package/src/client/useSubmitOperation.ts +25 -0
- package/src/client/usernameLocalStorage.ts +43 -0
- package/src/client/vzReducer/closeTabReducer.test.ts +177 -0
- package/src/client/vzReducer/closeTabsReducer.ts +68 -0
- package/src/client/vzReducer/createInitialState.ts +19 -0
- package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +9 -0
- package/src/client/vzReducer/index.ts +107 -0
- package/src/client/vzReducer/openTabReducer.test.ts +110 -0
- package/src/client/vzReducer/openTabReducer.ts +57 -0
- package/src/client/vzReducer/setActiveFileIdReducer.ts +9 -0
- package/src/client/vzReducer/setIsSettingsOpenReducer.ts +9 -0
- package/src/client/vzReducer/setThemeReducer.ts +9 -0
- package/src/client/vzReducer/setUsernameReducer.ts +9 -0
- package/src/index.ts +40 -0
- package/src/server/index.js +13 -2
- package/src/types.ts +12 -5
- package/dist/assets/index-8628ebab.js +0 -111
- package/dist/assets/index-cf19de3b.css +0 -1
- package/src/client/PrettierErrorOverlay/index.tsx +0 -9
- package/src/client/PrettierErrorOverlay/style.scss +0 -9
- package/src/client/Sidebar/Item.tsx +0 -130
- package/src/client/reducer.ts +0 -119
- /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,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
|
-
};
|
package/src/client/reducer.ts
DELETED
|
@@ -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
|
-
};
|
|
File without changes
|