vzcode 1.5.0 → 1.6.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.
@@ -5,10 +5,13 @@ import {
5
5
  FileTreeFile,
6
6
  } from '../../types';
7
7
  import { Tooltip, OverlayTrigger } from '../bootstrap';
8
+ import { Search } from './Search';
8
9
  import { getFileTree } from '../getFileTree';
9
10
  import { sortFileTree } from '../sortFileTree';
10
11
  import { SplitPaneResizeContext } from '../SplitPaneResizeContext';
11
12
  import {
13
+ FolderSVG,
14
+ SearchSVG,
12
15
  BugSVG,
13
16
  GearSVG,
14
17
  NewSVG,
@@ -31,18 +34,24 @@ export const VZSidebar = ({
31
34
  openSettingsTooltipText = 'Open Settings',
32
35
  openKeyboardShortcuts = 'Keyboard Shortcuts',
33
36
  reportBugTooltipText = 'Report Bug',
37
+ searchToolTipText = 'Search',
38
+ filesToolTipText = 'Files',
34
39
  }: {
35
40
  createFileTooltipText?: string;
36
41
  createDirTooltipText?: string;
37
42
  openSettingsTooltipText?: string;
38
43
  reportBugTooltipText?: string;
39
44
  openKeyboardShortcuts?: string;
45
+ searchToolTipText?: string;
46
+ filesToolTipText?: string;
40
47
  }) => {
41
48
  const {
42
49
  files,
43
50
  openTab,
44
51
  setIsSettingsOpen,
45
52
  setIsDocOpen,
53
+ isSearchOpen,
54
+ setIsSearchOpen,
46
55
  handleOpenCreateFileModal,
47
56
  handleOpenCreateDirModal,
48
57
  connected,
@@ -103,126 +112,170 @@ export const VZSidebar = ({
103
112
  onDragLeave={handleDragLeave}
104
113
  onDrop={handleDrop}
105
114
  >
106
- <div className="files" ref={sidebarRef} tabIndex={-1}>
107
- <div className="full-box">
108
- <div className="sidebar-section-hint">Files</div>
109
- <div className="sidebar-section-buttons">
110
- <OverlayTrigger
111
- placement="right"
112
- overlay={
113
- <Tooltip id="open-keyboard-shortcuts">
114
- {openKeyboardShortcuts}
115
- </Tooltip>
116
- }
115
+ <div
116
+ className="full-box"
117
+ ref={sidebarRef}
118
+ tabIndex={-1}
119
+ >
120
+ <div className="sidebar-section-buttons">
121
+ <OverlayTrigger
122
+ placement="right"
123
+ overlay={
124
+ <Tooltip id="files-tooltip">
125
+ {filesToolTipText}
126
+ </Tooltip>
127
+ }
128
+ >
129
+ <i
130
+ onClick={() => setIsSearchOpen(false)}
131
+ className="icon-button icon-button-dark"
117
132
  >
118
- <i
119
- onClick={handleQuestionMarkClick}
120
- className="icon-button icon-button-dark"
121
- >
122
- <QuestionMarkSVG />
123
- </i>
124
- </OverlayTrigger>
125
-
126
- <OverlayTrigger
127
- placement="right"
128
- overlay={
129
- <Tooltip id="report-bug-tooltip">
130
- {reportBugTooltipText}
131
- </Tooltip>
132
- }
133
+ <FolderSVG />
134
+ </i>
135
+ </OverlayTrigger>
136
+
137
+ <OverlayTrigger
138
+ placement="right"
139
+ overlay={
140
+ <Tooltip id="search-tooltip">
141
+ {searchToolTipText}
142
+ </Tooltip>
143
+ }
144
+ >
145
+ <i
146
+ onClick={() => setIsSearchOpen(true)}
147
+ className="icon-button icon-button-dark"
133
148
  >
134
- <a
135
- href="https://github.com/vizhub-core/vzcode/issues/new"
136
- target="_blank"
137
- rel="noopener noreferrer"
138
- >
139
- <i className="icon-button icon-button-dark">
140
- <BugSVG />
141
- </i>
142
- </a>
143
- </OverlayTrigger>
144
-
145
- <OverlayTrigger
146
- placement="left"
147
- overlay={
148
- <Tooltip id="open-settings-tooltip">
149
- {openSettingsTooltipText}
150
- </Tooltip>
151
- }
149
+ <SearchSVG />
150
+ </i>
151
+ </OverlayTrigger>
152
+
153
+ <OverlayTrigger
154
+ placement="right"
155
+ overlay={
156
+ <Tooltip id="open-keyboard-shortcuts">
157
+ {openKeyboardShortcuts}
158
+ </Tooltip>
159
+ }
160
+ >
161
+ <i
162
+ onClick={handleQuestionMarkClick}
163
+ className="icon-button icon-button-dark"
152
164
  >
153
- <i
154
- onClick={handleSettingsClick}
155
- className="icon-button icon-button-dark"
156
- >
157
- <GearSVG />
158
- </i>
159
- </OverlayTrigger>
160
-
161
- <OverlayTrigger
162
- placement="left"
163
- overlay={
164
- <Tooltip id="create-file-tooltip">
165
- {createFileTooltipText}
166
- </Tooltip>
167
- }
165
+ <QuestionMarkSVG />
166
+ </i>
167
+ </OverlayTrigger>
168
+
169
+ <OverlayTrigger
170
+ placement="right"
171
+ overlay={
172
+ <Tooltip id="report-bug-tooltip">
173
+ {reportBugTooltipText}
174
+ </Tooltip>
175
+ }
176
+ >
177
+ <a
178
+ href="https://github.com/vizhub-core/vzcode/issues/new"
179
+ target="_blank"
180
+ rel="noopener noreferrer"
168
181
  >
169
- <i
170
- onClick={handleOpenCreateFileModal}
171
- className="icon-button icon-button-dark"
172
- >
173
- <NewSVG />
182
+ <i className="icon-button icon-button-dark">
183
+ <BugSVG />
174
184
  </i>
175
- </OverlayTrigger>
176
-
177
- {/*Directory Rename*/}
178
- <OverlayTrigger
179
- placement="left"
180
- overlay={
181
- <Tooltip id="create-dir-tooltip">
182
- {createDirTooltipText}
183
- </Tooltip>
184
- }
185
+ </a>
186
+ </OverlayTrigger>
187
+
188
+ <OverlayTrigger
189
+ placement="right"
190
+ overlay={
191
+ <Tooltip id="open-settings-tooltip">
192
+ {openSettingsTooltipText}
193
+ </Tooltip>
194
+ }
195
+ >
196
+ <i
197
+ onClick={handleSettingsClick}
198
+ className="icon-button icon-button-dark"
185
199
  >
186
- <i
187
- onClick={handleOpenCreateDirModal}
188
- className="icon-button icon-button-dark"
189
- >
190
- <FileSVG />
191
- </i>
192
- </OverlayTrigger>
193
- </div>
200
+ <GearSVG />
201
+ </i>
202
+ </OverlayTrigger>
203
+
204
+ <OverlayTrigger
205
+ placement="right"
206
+ overlay={
207
+ <Tooltip id="create-file-tooltip">
208
+ {createFileTooltipText}
209
+ </Tooltip>
210
+ }
211
+ >
212
+ <i
213
+ onClick={handleOpenCreateFileModal}
214
+ className="icon-button icon-button-dark"
215
+ >
216
+ <NewSVG />
217
+ </i>
218
+ </OverlayTrigger>
219
+
220
+ {/*Directory Rename*/}
221
+ <OverlayTrigger
222
+ placement="right"
223
+ overlay={
224
+ <Tooltip id="create-dir-tooltip">
225
+ {createDirTooltipText}
226
+ </Tooltip>
227
+ }
228
+ >
229
+ <i
230
+ onClick={handleOpenCreateDirModal}
231
+ className="icon-button icon-button-dark"
232
+ >
233
+ <FileSVG />
234
+ </i>
235
+ </OverlayTrigger>
194
236
  </div>
195
- {isDragOver ? (
196
- <div className="empty">
197
- <div className="empty-text">
198
- Drop files here!
237
+
238
+ <div className="files">
239
+ {!isSearchOpen ? (
240
+ <div className="sidebar-files">
241
+ {isDragOver ? (
242
+ <div className="empty">
243
+ <div className="empty-text">
244
+ Drop files here!
245
+ </div>
246
+ </div>
247
+ ) : filesExist ? (
248
+ fileTree.children.map((entity) => {
249
+ const { fileId } = entity as FileTreeFile;
250
+ const { path } = entity as FileTree;
251
+ const key = fileId ? fileId : path;
252
+ return (
253
+ <Listing
254
+ key={key}
255
+ entity={entity}
256
+ handleFileClick={handleFileClick}
257
+ handleFileDoubleClick={
258
+ handleFileDoubleClick
259
+ }
260
+ />
261
+ );
262
+ })
263
+ ) : (
264
+ <div className="empty">
265
+ <div className="empty-text">
266
+ It looks like you don't have any files
267
+ yet! Click the "Create file" button
268
+ above to create your first file.
269
+ </div>
270
+ </div>
271
+ )}
199
272
  </div>
200
- </div>
201
- ) : filesExist ? (
202
- fileTree.children.map((entity) => {
203
- const { fileId } = entity as FileTreeFile;
204
- const { path } = entity as FileTree;
205
- const key = fileId ? fileId : path;
206
- return (
207
- <Listing
208
- key={key}
209
- entity={entity}
210
- handleFileClick={handleFileClick}
211
- handleFileDoubleClick={
212
- handleFileDoubleClick
213
- }
214
- />
215
- );
216
- })
217
- ) : (
218
- <div className="empty">
219
- <div className="empty-text">
220
- It looks like you don't have any files yet!
221
- Click the "Create file" button above to create
222
- your first file.
273
+ ) : (
274
+ <div className="sidebar-search">
275
+ <Search />
223
276
  </div>
224
- </div>
225
- )}
277
+ )}
278
+ </div>
226
279
  </div>
227
280
 
228
281
  {enableConnectionStatus && (
@@ -7,20 +7,25 @@
7
7
  justify-content: space-between;
8
8
 
9
9
  .full-box {
10
- padding: 4px;
10
+ width: 100%;
11
+ height: 100%;
11
12
  display: flex;
12
13
  flex-direction: row;
13
- align-items: center;
14
- justify-content: space-between;
14
+ justify-content: start;
15
+ align-items: start;
15
16
  border-bottom: 2px solid var(--vh-color-neutral-02);
17
+ overflow: hidden;
16
18
  }
17
19
 
18
20
  .files {
19
- overflow: auto;
20
21
  display: flex;
21
- flex-direction: column;
22
+ flex-direction: row;
23
+ justify-content: start;
24
+ align-items: start;
22
25
  flex: 1;
23
26
  outline: none;
27
+ overflow: auto;
28
+ height: 100%;
24
29
  }
25
30
 
26
31
  .file-or-directory {
@@ -30,8 +35,8 @@
30
35
  align-items: center;
31
36
  justify-content: space-between;
32
37
  cursor: pointer;
33
- margin: 0 10px;
34
- padding: 0 4px 0 8px;
38
+ margin: 0 8px;
39
+ padding: 0 4px 0 6px;
35
40
  border-radius: 4px;
36
41
  font-family: var(--vzcode-font-family);
37
42
  font-weight: 500;
@@ -46,14 +51,100 @@
46
51
  }
47
52
 
48
53
  .sidebar-section-buttons {
54
+ border-right: 2px solid var(--vh-color-neutral-02);
55
+ height: 100%;
49
56
  display: flex;
50
- flex-direction: row;
57
+ flex-direction: column;
51
58
  align-items: center;
52
- a {
59
+ gap: 6px;
60
+ padding: 6px;
61
+
62
+ * {
63
+ color: inherit;
64
+ }
65
+ }
66
+
67
+ .sidebar-files,
68
+ .sidebar-search {
69
+ width: 100%;
70
+ }
71
+
72
+ .sidebar-search {
73
+ padding: 10px;
74
+
75
+ * {
53
76
  color: inherit;
54
77
  }
55
78
  }
56
79
 
80
+ .search-result-lines {
81
+ margin-top: 10px;
82
+ margin-left: 20px;
83
+ }
84
+
85
+ .search-file-heading {
86
+ display: flex;
87
+ justify-content: space-between;
88
+ align-items: center;
89
+
90
+ * {
91
+ margin: 0px;
92
+ }
93
+ }
94
+
95
+ .search-file-title,
96
+ .search-file-name,
97
+ .search-file-info {
98
+ display: flex;
99
+ justify-content: center;
100
+ align-items: center;
101
+ gap: 10px;
102
+ }
103
+
104
+ .search-file-name {
105
+ font-size: inherit;
106
+ }
107
+
108
+ .search-file-count {
109
+ width: 18px;
110
+ height: 18px;
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: center;
114
+ margin: 0px;
115
+ font-size: 12px;
116
+ font-weight: bold;
117
+ text-align: center;
118
+ background: var(--vh-color-neutral-04);
119
+ color: var(--vh-color-neutral-01);
120
+ border-radius: 100%;
121
+ }
122
+
123
+ .search-results {
124
+ padding: 10px;
125
+ }
126
+
127
+ .search-file-lines {
128
+ font-size: inherit;
129
+ margin: 15px 0px 0px 30px;
130
+ }
131
+
132
+ .search-line,
133
+ .arrow-wrapper,
134
+ .search-file-close {
135
+ &:hover {
136
+ opacity: 0.7;
137
+ cursor: pointer;
138
+ }
139
+ }
140
+
141
+ .search-file-lines .search-pattern {
142
+ background: var(--vh-color-neutral-04);
143
+ color: var(--vh-color-neutral-01);
144
+ margin: 0.5px;
145
+ padding: 1px;
146
+ }
147
+
57
148
  .new-btn {
58
149
  justify-content: right;
59
150
  margin-right: 10px;
@@ -82,7 +173,7 @@
82
173
  align-items: center;
83
174
  white-space: nowrap;
84
175
  overflow: hidden;
85
- gap: 8px;
176
+ gap: 6px;
86
177
  .file-icon,
87
178
  .arrow-wrapper {
88
179
  opacity: 0.5;
@@ -1,6 +1,12 @@
1
1
  import { useCallback } from 'react';
2
2
  import { ThemeLabel } from './themes';
3
- import { FileId, Username } from '../types';
3
+ import {
4
+ FileId,
5
+ SearchFileVisibility,
6
+ ShareDBDoc,
7
+ Username,
8
+ VZCodeContent,
9
+ } from '../types';
4
10
  import { TabState, VZAction } from './vzReducer';
5
11
 
6
12
  // This is a custom hook that returns a set of functions
@@ -57,6 +63,56 @@ export const useActions = (
57
63
  [dispatch],
58
64
  );
59
65
 
66
+ // True to show the settings modal.
67
+ const setIsSearchOpen = useCallback(
68
+ (value: boolean) => {
69
+ dispatch({
70
+ type: 'set_is_search_open',
71
+ value: value,
72
+ });
73
+ },
74
+ [dispatch],
75
+ );
76
+
77
+ // Update search pattern
78
+ const setSearch = useCallback(
79
+ (pattern: string) => {
80
+ dispatch({
81
+ type: 'set_search',
82
+ value: pattern,
83
+ });
84
+ },
85
+ [dispatch],
86
+ );
87
+
88
+ // Update search results based on current pattern
89
+ const setSearchResults = useCallback(
90
+ (files: ShareDBDoc<VZCodeContent>) => {
91
+ dispatch({
92
+ type: 'set_search_results',
93
+ files: files,
94
+ });
95
+ },
96
+ [dispatch],
97
+ );
98
+
99
+ // Update search results file visibility based on current pattern
100
+ const setSearchFileVisibility = useCallback(
101
+ (
102
+ files: ShareDBDoc<VZCodeContent>,
103
+ id: string,
104
+ visibility: SearchFileVisibility,
105
+ ) => {
106
+ dispatch({
107
+ type: 'set_search_file_visibility',
108
+ files: files,
109
+ id: id,
110
+ visibility: visibility,
111
+ });
112
+ },
113
+ [dispatch],
114
+ );
115
+
60
116
  // True to show the settings modal.
61
117
  const setIsSettingsOpen = useCallback(
62
118
  (value: boolean) => {
@@ -109,6 +165,10 @@ export const useActions = (
109
165
  openTab,
110
166
  closeTabs,
111
167
  setTheme,
168
+ setIsSearchOpen,
169
+ setSearch,
170
+ setSearchResults,
171
+ setSearchFileVisibility,
112
172
  setIsSettingsOpen,
113
173
  setIsDocOpen,
114
174
  closeSettings,
@@ -1,4 +1,4 @@
1
- import { useCallback, useState } from 'react';
1
+ import { useCallback } from 'react';
2
2
  import {
3
3
  FileId,
4
4
  FileTreePath,
@@ -12,6 +12,8 @@ export const createInitialState = ({
12
12
  tabList: [],
13
13
  activeFileId: null,
14
14
  theme: defaultTheme,
15
+ search: { pattern: '', results: {} },
16
+ isSearchOpen: false,
15
17
  isSettingsOpen: false,
16
18
  isDocOpen: false,
17
19
  editorWantsFocus: false,
@@ -1,4 +1,11 @@
1
- import { FileId, Username } from '../../types';
1
+ import {
2
+ FileId,
3
+ SearchFileVisibility,
4
+ SearchResults,
5
+ ShareDBDoc,
6
+ Username,
7
+ VZCodeContent,
8
+ } from '../../types';
2
9
  import { ThemeLabel } from '../themes';
3
10
  import { closeTabsReducer } from './closeTabsReducer';
4
11
  import { openTabReducer } from './openTabReducer';
@@ -12,7 +19,12 @@ import { setIsDocOpenReducer } from './setIsDocOpenReducer';
12
19
  import { setThemeReducer } from './setThemeReducer';
13
20
  import { editorNoLongerWantsFocusReducer } from './editorNoLongerWantsFocusReducer';
14
21
  import { setUsernameReducer } from './setUsernameReducer';
15
-
22
+ import {
23
+ setIsSearchOpenReducer,
24
+ setSearchReducer,
25
+ setSearchResultsReducer,
26
+ setSearchFileVisibilityReducer,
27
+ } from './searchReducer';
16
28
  export { createInitialState } from './createInitialState';
17
29
 
18
30
  // The shape of the state managed by the reducer.
@@ -27,6 +39,12 @@ export type VZState = {
27
39
  // The theme that is currently active.
28
40
  theme: ThemeLabel;
29
41
 
42
+ // Search pattern and most recent results based on the current pattern
43
+ search: SearchResults;
44
+
45
+ // True to show the search instead of files
46
+ isSearchOpen: boolean;
47
+
30
48
  // True to show the settings modal.
31
49
  isSettingsOpen: boolean;
32
50
 
@@ -73,6 +91,30 @@ export type VZAction =
73
91
  | { type: 'set_is_settings_open'; value: boolean }
74
92
  | { type: 'set_is_doc_open'; value: boolean }
75
93
 
94
+ // `set_is_search_open`
95
+ // * Sets whether the search tab is open.
96
+ | { type: 'set_is_search_open'; value: boolean }
97
+
98
+ // `set_search`
99
+ // * Sets the current search pattern
100
+ | { type: 'set_search'; value: string }
101
+
102
+ // `set_search_results`
103
+ // * Sets the current search pattern
104
+ | {
105
+ type: 'set_search_results';
106
+ files: ShareDBDoc<VZCodeContent>;
107
+ }
108
+
109
+ // `set_search_results_visibility`
110
+ // * Sets the visibility of a current search pattern file
111
+ | {
112
+ type: 'set_search_file_visibility';
113
+ files: ShareDBDoc<VZCodeContent>;
114
+ id: string;
115
+ visibility: SearchFileVisibility;
116
+ }
117
+
76
118
  // `editor_no_longer_wants_focus`
77
119
  // * Sets `editorWantsFocus` to `false`.
78
120
  | { type: 'editor_no_longer_wants_focus' }
@@ -107,6 +149,10 @@ const reducers = [
107
149
  openTabReducer,
108
150
  closeTabsReducer,
109
151
  setThemeReducer,
152
+ setSearchReducer,
153
+ setSearchResultsReducer,
154
+ setSearchFileVisibilityReducer,
155
+ setIsSearchOpenReducer,
110
156
  setIsSettingsOpenReducer,
111
157
  setIsDocOpenReducer,
112
158
  editorNoLongerWantsFocusReducer,