@danixl30/file-explorer-cli 1.0.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 (110) hide show
  1. package/LICENSE +21 -0
  2. package/dist/alerts/AlertContextProvider.js +13 -0
  3. package/dist/alerts/components/AlertDisplay.js +19 -0
  4. package/dist/alerts/logic/alert.logic.js +16 -0
  5. package/dist/app.js +27 -0
  6. package/dist/bookmark/Bookmark.js +123 -0
  7. package/dist/bookmark/components/BookmarkList.js +47 -0
  8. package/dist/bookmark/context/BookmarkPaneContext.js +9 -0
  9. package/dist/bookmark/events/add.item.js +8 -0
  10. package/dist/bookmark/implementations/clean.bookmarks.js +6 -0
  11. package/dist/bookmark/implementations/get.all.bookmarks.js +2 -0
  12. package/dist/bookmark/implementations/save.bookmarks.js +5 -0
  13. package/dist/bookmark/logic/bookmark.manager.js +25 -0
  14. package/dist/bookmark/services/clean.bookmarks.js +1 -0
  15. package/dist/bookmark/services/get.all.bookmarks.js +1 -0
  16. package/dist/bookmark/services/write.bookmarks.js +1 -0
  17. package/dist/bookmark/types/bookmark.js +1 -0
  18. package/dist/cli.js +31 -0
  19. package/dist/clipboard/ClipboardProvider.js +8 -0
  20. package/dist/clipboard/logic/clipboard-logic.js +10 -0
  21. package/dist/core/application/event-handler/event-handler.js +1 -0
  22. package/dist/core/application/event-handler/listener/event-listener.js +1 -0
  23. package/dist/core/application/event-handler/types/event.js +1 -0
  24. package/dist/core/application/event-handler/types/subscription.js +1 -0
  25. package/dist/core/application/id-generator/id.generator.js +1 -0
  26. package/dist/core/application/init-layout/init-layout.js +1 -0
  27. package/dist/core/application/input-manager/input-manager.js +1 -0
  28. package/dist/core/application/input-manager/types/input-manager-result.js +1 -0
  29. package/dist/core/application/on-init/on-init.js +1 -0
  30. package/dist/core/application/on-init-job/lazy/on-init-job-lazy.js +1 -0
  31. package/dist/core/application/on-init-job/on-init-job.js +1 -0
  32. package/dist/core/application/pagination-manager/pagination-manager.js +1 -0
  33. package/dist/core/application/pagination-manager/types/pagination-result.js +1 -0
  34. package/dist/core/application/service/application-service.js +1 -0
  35. package/dist/core/application/state/state-factory.js +1 -0
  36. package/dist/core/application/state/state-provider.js +1 -0
  37. package/dist/core/application/state-observers/state-observer.js +1 -0
  38. package/dist/core/application/timer/sleep/sleep.js +1 -0
  39. package/dist/core/application/timer/timer.js +19 -0
  40. package/dist/core/application/value-provider/value-provider.js +1 -0
  41. package/dist/core/infraestructure/db/bookmark.db.js +4 -0
  42. package/dist/core/infraestructure/event-handler/context/EventProvider.js +9 -0
  43. package/dist/core/infraestructure/event-handler/listener/event-listener-factory.js +8 -0
  44. package/dist/core/infraestructure/event-handler/useEventHadler.js +27 -0
  45. package/dist/core/infraestructure/initLayout/useLayoutEffectOnInit.js +4 -0
  46. package/dist/core/infraestructure/input-manager/useInputManager.js +14 -0
  47. package/dist/core/infraestructure/on-init/useEffectOnInit.js +9 -0
  48. package/dist/core/infraestructure/on-init-job/nativeOnInitJob.js +37 -0
  49. package/dist/core/infraestructure/on-init-job/nativeOnInitJobLazy.js +32 -0
  50. package/dist/core/infraestructure/pagination-manager/data-transforms/infinite.js +1 -0
  51. package/dist/core/infraestructure/pagination-manager/data-transforms/normal.js +1 -0
  52. package/dist/core/infraestructure/pagination-manager/usePaginationManager.js +59 -0
  53. package/dist/core/infraestructure/state/useRefStateProvider.js +39 -0
  54. package/dist/core/infraestructure/state/useStateProvider.js +35 -0
  55. package/dist/core/infraestructure/state-observer/useEffectStateObserver.js +16 -0
  56. package/dist/core/infraestructure/timer/sleep.js +2 -0
  57. package/dist/core/infraestructure/uuid/uuid.generator.js +2 -0
  58. package/dist/core/infraestructure/value-provider/useRefValueProvider.js +12 -0
  59. package/dist/core/utils/argument.type.js +1 -0
  60. package/dist/core/utils/optional.js +1 -0
  61. package/dist/file-display/FileDisplay.js +456 -0
  62. package/dist/file-display/components/Loading.js +4 -0
  63. package/dist/file-display/components/NodeDetails.js +50 -0
  64. package/dist/file-display/components/NodeList.js +61 -0
  65. package/dist/file-display/events/node.written.js +7 -0
  66. package/dist/file-display/hooks/useResize.js +24 -0
  67. package/dist/file-display/implementation/create.dir.js +7 -0
  68. package/dist/file-display/implementation/delete.js +9 -0
  69. package/dist/file-display/implementation/execute.command.async.js +6 -0
  70. package/dist/file-display/implementation/execute.command.sync.js +9 -0
  71. package/dist/file-display/implementation/execute.file.js +4 -0
  72. package/dist/file-display/implementation/filter.glob.js +4 -0
  73. package/dist/file-display/implementation/get.all.files.js +44 -0
  74. package/dist/file-display/implementation/get.directory.js +8 -0
  75. package/dist/file-display/implementation/get.upper.directory.js +17 -0
  76. package/dist/file-display/implementation/move.trash.js +9 -0
  77. package/dist/file-display/implementation/node.details.js +79 -0
  78. package/dist/file-display/implementation/paste.operation.js +40 -0
  79. package/dist/file-display/implementation/rename.js +6 -0
  80. package/dist/file-display/logic/file.manager.js +107 -0
  81. package/dist/file-display/logic/history.manager.js +47 -0
  82. package/dist/file-display/logic/node.detail.js +8 -0
  83. package/dist/file-display/logic/operations.manager.js +103 -0
  84. package/dist/file-display/services/create.dir.js +1 -0
  85. package/dist/file-display/services/delete.js +1 -0
  86. package/dist/file-display/services/execute.command.async.js +1 -0
  87. package/dist/file-display/services/execute.command.sync.js +1 -0
  88. package/dist/file-display/services/execute.file.js +1 -0
  89. package/dist/file-display/services/filter.glob.js +1 -0
  90. package/dist/file-display/services/get.all.files.js +1 -0
  91. package/dist/file-display/services/get.directory.js +1 -0
  92. package/dist/file-display/services/get.upper.directory.js +1 -0
  93. package/dist/file-display/services/move.trash.js +1 -0
  94. package/dist/file-display/services/node.details.js +1 -0
  95. package/dist/file-display/services/paste.operation.js +1 -0
  96. package/dist/file-display/services/remane.js +1 -0
  97. package/dist/file-display/types/node.details.js +1 -0
  98. package/dist/file-display/types/node.js +1 -0
  99. package/dist/file-display/utils/icon.parser.js +144 -0
  100. package/dist/input-capture/InputCapureWrapper.js +10 -0
  101. package/dist/input-capture/InputContextCapture.js +26 -0
  102. package/dist/tabs/TabsContext.js +17 -0
  103. package/dist/tabs/events/update.tab.data.js +8 -0
  104. package/dist/tabs/events/update.tab.selection.js +8 -0
  105. package/dist/tabs/logic/tabsManagerLogic.js +58 -0
  106. package/dist/tabs/wrapper/tabs.wrapper.js +38 -0
  107. package/dist/text-field/TextFieldCaptureContext.js +24 -0
  108. package/dist/text-field/TextFieldWrapper.js +21 -0
  109. package/package.json +62 -0
  110. package/readme.md +57 -0
@@ -0,0 +1,32 @@
1
+ export const nativeOnInitJob = (stateFactory) => (callback, onTask) => {
2
+ const dataState = stateFactory(null);
3
+ const loadingState = stateFactory(false);
4
+ const errorState = stateFactory(null);
5
+ const doJob = async (...args) => {
6
+ if (loadingState.state)
7
+ throw new Error('Is in job');
8
+ dataState.setState(null);
9
+ errorState.setState(null);
10
+ loadingState.setState(true);
11
+ const loadingTask = onTask?.();
12
+ try {
13
+ const res = await callback(...args);
14
+ dataState.setState(res);
15
+ loadingState.setState(false);
16
+ loadingTask?.success?.();
17
+ return res;
18
+ }
19
+ catch (e) {
20
+ errorState.setState(e);
21
+ loadingTask?.error?.(e);
22
+ loadingState.setState(false);
23
+ throw e;
24
+ }
25
+ };
26
+ return {
27
+ do: doJob,
28
+ data: dataState.state,
29
+ error: errorState.state,
30
+ isLoading: loadingState.state,
31
+ };
32
+ };
@@ -0,0 +1 @@
1
+ export const infiniteDataTransform = () => (res, prev) => [...prev, ...res];
@@ -0,0 +1 @@
1
+ export const normalDataTransform = () => (res, _prev) => res;
@@ -0,0 +1,59 @@
1
+ import { normalDataTransform } from './data-transforms/normal.js';
2
+ export const usePaginationManager = (stateFactory, stateObserver, onInit) => (callback, dataTransform = normalDataTransform()) => {
3
+ const pageState = stateFactory(1);
4
+ const dataState = stateFactory([]);
5
+ const errorState = stateFactory(null);
6
+ const loadingState = stateFactory(false);
7
+ const isTopState = stateFactory(false);
8
+ const job = async () => {
9
+ if (loadingState.state.value)
10
+ return;
11
+ loadingState.setState(true);
12
+ errorState.setState(null);
13
+ try {
14
+ const data = await callback(pageState.state.value);
15
+ if (data.length === 0)
16
+ isTopState.setState(true);
17
+ dataState.setState(dataTransform(data, dataState.state.value));
18
+ }
19
+ catch (e) {
20
+ errorState.setState(e);
21
+ }
22
+ loadingState.setState(false);
23
+ };
24
+ onInit(() => {
25
+ job();
26
+ });
27
+ stateObserver(() => {
28
+ job();
29
+ }, pageState.state);
30
+ const increment = () => pageState.setState(pageState.state.value + 1);
31
+ const reset = () => {
32
+ isTopState.setState(false);
33
+ dataState.setState([]);
34
+ pageState.setState(1);
35
+ job();
36
+ };
37
+ const previousPage = () => {
38
+ isTopState.setState(false);
39
+ if (pageState.state.value > 2)
40
+ pageState.setState(pageState.state.value - 1);
41
+ };
42
+ const setPage = (page) => {
43
+ isTopState.setState(false);
44
+ if (page < 1 || Math.ceil(page) !== page)
45
+ throw new Error('Invalid page');
46
+ pageState.setState(page);
47
+ };
48
+ return {
49
+ data: dataState.state,
50
+ error: errorState.state,
51
+ isLoading: loadingState.state,
52
+ increment,
53
+ reset,
54
+ page: pageState.state,
55
+ previousPage,
56
+ setPage,
57
+ isTop: isTopState.state,
58
+ };
59
+ };
@@ -0,0 +1,39 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ export const useRefStateFactory = () => {
3
+ const [_, forceUpdate] = useState(0);
4
+ const isMounted = useRef(true);
5
+ useEffect(() => {
6
+ isMounted.current = true;
7
+ return () => {
8
+ isMounted.current = false;
9
+ };
10
+ }, []);
11
+ return (initialize) => {
12
+ const subscriptors = useRef([]);
13
+ const firstTime = useRef(true);
14
+ const state = useRef(initialize);
15
+ useEffect(() => {
16
+ if (firstTime.current) {
17
+ firstTime.current = false;
18
+ return;
19
+ }
20
+ subscriptors.current.forEach((e) => e(state.current));
21
+ }, [state]);
22
+ return {
23
+ state: {
24
+ get value() {
25
+ return state.current;
26
+ },
27
+ subscribe(callback) {
28
+ subscriptors.current.push(callback);
29
+ },
30
+ },
31
+ setState(value) {
32
+ if (!isMounted.current)
33
+ return;
34
+ state.current = value;
35
+ forceUpdate((value) => ++value);
36
+ },
37
+ };
38
+ };
39
+ };
@@ -0,0 +1,35 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ export const useStateFactory = (initialize) => {
3
+ const subscriptors = useRef([]);
4
+ const firstTime = useRef(true);
5
+ const isMounted = useRef(true);
6
+ const [state, setState] = useState(initialize);
7
+ useEffect(() => {
8
+ if (firstTime.current) {
9
+ firstTime.current = false;
10
+ return;
11
+ }
12
+ subscriptors.current.forEach((e) => e(state));
13
+ }, [state]);
14
+ useEffect(() => {
15
+ isMounted.current = true;
16
+ return () => {
17
+ isMounted.current = false;
18
+ };
19
+ }, []);
20
+ return {
21
+ state: {
22
+ get value() {
23
+ return state;
24
+ },
25
+ subscribe(callback) {
26
+ subscriptors.current.push(callback);
27
+ },
28
+ },
29
+ setState(value) {
30
+ if (!isMounted.current)
31
+ return;
32
+ setState(value);
33
+ },
34
+ };
35
+ };
@@ -0,0 +1,16 @@
1
+ import { useEffect, useRef } from 'react';
2
+ export const useEffectStateObserver = (callback, ...states) => {
3
+ if (states.length === 0)
4
+ return;
5
+ const firstTime = useRef(true);
6
+ useEffect(() => {
7
+ if (firstTime.current) {
8
+ firstTime.current = false;
9
+ return;
10
+ }
11
+ const res = callback();
12
+ return () => {
13
+ res?.();
14
+ };
15
+ }, [...states.map((e) => e.value)]);
16
+ };
@@ -0,0 +1,2 @@
1
+ import { setTimeout } from 'node:timers/promises';
2
+ export const setTimeoutSleep = (time) => setTimeout(time);
@@ -0,0 +1,2 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ export const uuidGenerator = () => randomUUID();
@@ -0,0 +1,12 @@
1
+ import { useRef } from 'react';
2
+ export const useRefValueProvider = () => (initialValue) => {
3
+ const ref = useRef(initialValue);
4
+ return {
5
+ get value() {
6
+ return ref.current;
7
+ },
8
+ set value(value) {
9
+ ref.current = value;
10
+ },
11
+ };
12
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,456 @@
1
+ import { existsSync } from 'node:fs';
2
+ import clipboardy from 'clipboardy';
3
+ import { Box, Text, useInput } from 'ink';
4
+ import React, { useContext, useRef, useState } from 'react';
5
+ import { AlertContext } from '../alerts/AlertContextProvider.js';
6
+ import { BookmarkPaneContext } from '../bookmark/context/BookmarkPaneContext.js';
7
+ import { createAddBookmarkItem } from '../bookmark/events/add.item.js';
8
+ import { ClipboardContext } from '../clipboard/ClipboardProvider.js';
9
+ import { EventContext } from '../core/infraestructure/event-handler/context/EventProvider.js';
10
+ import { nativeOnInitJob } from '../core/infraestructure/on-init-job/nativeOnInitJob.js';
11
+ import { useEffectOnInit } from '../core/infraestructure/on-init/useEffectOnInit.js';
12
+ import { useEffectStateObserver } from '../core/infraestructure/state-observer/useEffectStateObserver.js';
13
+ import { useRefStateFactory } from '../core/infraestructure/state/useRefStateProvider.js';
14
+ import { useRefValueProvider } from '../core/infraestructure/value-provider/useRefValueProvider.js';
15
+ import { InputContextCapture } from '../input-capture/InputContextCapture.js';
16
+ import { TabsContext } from '../tabs/TabsContext.js';
17
+ import { TextFieldContextCapture } from '../text-field/TextFieldCaptureContext.js';
18
+ import { NodeDetails } from './components/NodeDetails.js';
19
+ import { NodeList } from './components/NodeList.js';
20
+ import { createNodeWrittenEvent } from './events/node.written.js';
21
+ import { createDirectory } from './implementation/create.dir.js';
22
+ import { deleteNode } from './implementation/delete.js';
23
+ import { executeCommandAsync } from './implementation/execute.command.async.js';
24
+ import { executeCommandSync } from './implementation/execute.command.sync.js';
25
+ import { executeFile } from './implementation/execute.file.js';
26
+ import { filterByGlobPattern } from './implementation/filter.glob.js';
27
+ import { getAllFiles } from './implementation/get.all.files.js';
28
+ import { getNextDir } from './implementation/get.directory.js';
29
+ import { getUpperDirectory } from './implementation/get.upper.directory.js';
30
+ import { moveNodeToTrash } from './implementation/move.trash.js';
31
+ import { pasteOperation } from './implementation/paste.operation.js';
32
+ import { renameNode } from './implementation/rename.js';
33
+ import { fileManagerLogic } from './logic/file.manager.js';
34
+ import { historyManager } from './logic/history.manager.js';
35
+ import { operationsManager } from './logic/operations.manager.js';
36
+ export default function FileDisplay(props) {
37
+ const isInputEnable = useRef(true);
38
+ const stateFactory = useRefStateFactory();
39
+ const tabs = useContext(TabsContext);
40
+ const alert = useContext(AlertContext);
41
+ const inputCapture = useContext(InputContextCapture);
42
+ const [index, setIndex] = useState(-1);
43
+ const clipboard = useContext(ClipboardContext);
44
+ const textField = useContext(TextFieldContextCapture);
45
+ const eventHandler = useContext(EventContext);
46
+ const { isBookmarkEnabled } = useContext(BookmarkPaneContext);
47
+ const history = historyManager(useRefValueProvider(), eventHandler, props.initialData.history);
48
+ const files = fileManagerLogic(stateFactory, useEffectStateObserver, eventHandler, nativeOnInitJob(stateFactory, useEffectStateObserver, useEffectOnInit), props.initialData.path, getAllFiles, getUpperDirectory, getNextDir, executeFile, history, props.selection, filterByGlobPattern);
49
+ const operations = operationsManager(files, clipboard, pasteOperation, deleteNode, renameNode, createDirectory, executeCommandSync, executeCommandAsync, moveNodeToTrash);
50
+ const filesList = files.files.value ?? [];
51
+ const moveUpArrow = () => {
52
+ setIndex((prev) => {
53
+ if (prev <= -1)
54
+ return prev;
55
+ return prev - 1;
56
+ });
57
+ };
58
+ const moveDownArrow = () => {
59
+ setIndex((prev) => {
60
+ if (!filesList.length)
61
+ return -1;
62
+ if (prev + 1 >= filesList.length)
63
+ return filesList.length - 1;
64
+ return prev + 1;
65
+ });
66
+ };
67
+ const setCut = () => {
68
+ if (index < 0 || index >= filesList.length)
69
+ return;
70
+ if (filesList[index]?.type === 'DRIVE')
71
+ return;
72
+ operations.cut(filesList[index]);
73
+ alert.setAlert({
74
+ kind: 'INFO',
75
+ message: 'File added to clipboard to cut',
76
+ });
77
+ };
78
+ const setCopy = () => {
79
+ if (index < 0 || index >= filesList.length)
80
+ return;
81
+ if (filesList[index]?.type === 'DRIVE')
82
+ return;
83
+ operations.copy(filesList[index]);
84
+ alert.setAlert({
85
+ kind: 'INFO',
86
+ message: 'File added to clipboard to copy',
87
+ });
88
+ };
89
+ const executePaste = async (force) => {
90
+ if (!clipboard.item.value)
91
+ return;
92
+ isInputEnable.current = false;
93
+ alert.alertControlled({
94
+ kind: 'INFO',
95
+ message: clipboard.item.value.opeation === 'COPY'
96
+ ? 'Coping item...'
97
+ : 'Cutting item...',
98
+ });
99
+ try {
100
+ await operations.paste(force);
101
+ alert.setAlert({
102
+ message: 'Paste successfull',
103
+ kind: 'SUCCESS',
104
+ });
105
+ eventHandler.publish(createNodeWrittenEvent());
106
+ }
107
+ catch (error) {
108
+ alert.setAlert({
109
+ kind: 'ERR',
110
+ message: error.message,
111
+ });
112
+ }
113
+ isInputEnable.current = true;
114
+ };
115
+ const openDirInNewTab = () => {
116
+ if (index < 0 || index >= filesList.length)
117
+ return;
118
+ const node = filesList[index];
119
+ if (node.type === 'FILE')
120
+ return;
121
+ tabs.addTab({
122
+ path: node.path,
123
+ history: {
124
+ forward: [],
125
+ previous: [],
126
+ },
127
+ });
128
+ };
129
+ const selectItem = () => {
130
+ if (index === -1)
131
+ files.gotToUpper();
132
+ else if (filesList[index])
133
+ files.selectNode(filesList[index]);
134
+ };
135
+ const deleteItem = () => {
136
+ if (index < 0 || index >= filesList.length)
137
+ return;
138
+ const node = filesList[index];
139
+ if (node.type === 'DRIVE')
140
+ return;
141
+ inputCapture.addCallback(async (key) => {
142
+ if (key !== 'Y')
143
+ return;
144
+ isInputEnable.current = false;
145
+ alert.alertControlled({
146
+ kind: 'INFO',
147
+ message: 'Deleting item...',
148
+ });
149
+ try {
150
+ await operations.removeNode(node);
151
+ alert.setAlert({
152
+ message: 'Delete successfull',
153
+ kind: 'SUCCESS',
154
+ });
155
+ eventHandler.publish(createNodeWrittenEvent());
156
+ }
157
+ catch (error) {
158
+ alert.setAlert({
159
+ kind: 'ERR',
160
+ message: error.message,
161
+ });
162
+ }
163
+ isInputEnable.current = true;
164
+ }, 'Do you want to remove this item? Y/n');
165
+ };
166
+ const createDir = () => {
167
+ if (filesList.some((e) => e.type === 'DRIVE'))
168
+ return;
169
+ textField.addCallback({
170
+ placeHolder: 'Set folder name',
171
+ callback: {
172
+ onSuccess: async (data) => {
173
+ if (!data)
174
+ return;
175
+ try {
176
+ await operations.createDirectory(data);
177
+ alert.setAlert({
178
+ message: 'Folder created',
179
+ kind: 'SUCCESS',
180
+ });
181
+ }
182
+ catch (error) {
183
+ alert.setAlert({
184
+ kind: 'ERR',
185
+ message: error.message,
186
+ });
187
+ }
188
+ },
189
+ onChange: (data) => {
190
+ if (!data ||
191
+ files.files.value?.some((e) => e.name === data))
192
+ textField.setError('Element already exist');
193
+ else
194
+ textField.setError('');
195
+ },
196
+ },
197
+ });
198
+ };
199
+ const renameItem = () => {
200
+ if (index < 0 || index >= filesList.length || selections.length)
201
+ return;
202
+ const node = filesList[index];
203
+ if (node.type === 'DRIVE')
204
+ return;
205
+ textField.addCallback({
206
+ placeHolder: 'Set item name',
207
+ defaultValue: node.name,
208
+ text: 'Rename item name',
209
+ callback: {
210
+ onSuccess: async (data) => {
211
+ if (!data)
212
+ return;
213
+ try {
214
+ await operations.rename(node, data);
215
+ alert.setAlert({
216
+ message: 'Item renamed',
217
+ kind: 'SUCCESS',
218
+ });
219
+ eventHandler.publish(createNodeWrittenEvent());
220
+ }
221
+ catch (error) {
222
+ alert.setAlert({
223
+ kind: 'ERR',
224
+ message: error.message,
225
+ });
226
+ }
227
+ },
228
+ onChange: (data) => {
229
+ if (!data ||
230
+ (data !== node.name &&
231
+ files.files.value?.some((e) => e.name === data)))
232
+ textField.setError('Element already exist');
233
+ else
234
+ textField.setError('');
235
+ },
236
+ },
237
+ });
238
+ };
239
+ const toggleSelectItem = () => {
240
+ if (index < 0 || index >= filesList.length)
241
+ return;
242
+ const node = filesList[index];
243
+ if (node.type === 'DRIVE')
244
+ return;
245
+ files.toggleSelected(node);
246
+ };
247
+ const selectToDetails = () => {
248
+ if (index < 0 || index >= filesList.length)
249
+ return;
250
+ const node = filesList[index];
251
+ files.selectNodeToDetails(node);
252
+ };
253
+ const addToBookmark = () => {
254
+ if (index < 0 || index >= filesList.length)
255
+ return;
256
+ const node = filesList[index];
257
+ if (node.type === 'FILE')
258
+ return;
259
+ eventHandler.publish(createAddBookmarkItem(node));
260
+ };
261
+ const copyNodePathToClipboard = () => {
262
+ if (index < 0 || index >= filesList.length)
263
+ return;
264
+ const node = filesList[index];
265
+ clipboardy.writeSync(node.path);
266
+ alert.setAlert({
267
+ kind: 'INFO',
268
+ message: 'Item path added to clipboard',
269
+ });
270
+ };
271
+ const copyPathToClipboard = () => {
272
+ clipboardy.writeSync(files.path.value);
273
+ alert.setAlert({
274
+ kind: 'INFO',
275
+ message: 'Current dir path added to clipboard',
276
+ });
277
+ };
278
+ const runCommandAsync = () => {
279
+ textField.addCallback({
280
+ placeHolder: 'Command in background...',
281
+ callback: {
282
+ onSuccess: async (command) => {
283
+ await operations.runCommandAsync(command);
284
+ },
285
+ onChange: async () => { },
286
+ },
287
+ });
288
+ };
289
+ const runCommandSync = () => {
290
+ textField.addCallback({
291
+ placeHolder: 'Command blocking...',
292
+ callback: {
293
+ onSuccess: async (command) => {
294
+ isInputEnable.current = false;
295
+ await operations
296
+ .runCommandSync(command)
297
+ .then((data) => alert.setAlert({
298
+ kind: 'INFO',
299
+ message: data,
300
+ }))
301
+ .catch((err) => alert.setAlert({
302
+ kind: 'ERR',
303
+ message: err.message,
304
+ }));
305
+ isInputEnable.current = true;
306
+ },
307
+ onChange: async () => { },
308
+ },
309
+ });
310
+ };
311
+ const setPath = () => {
312
+ textField.addCallback({
313
+ placeHolder: 'Set path',
314
+ defaultValue: files.path.value,
315
+ text: 'Navigate to path',
316
+ callback: {
317
+ onSuccess: async (data) => {
318
+ if (!data)
319
+ return;
320
+ files.navigateTo(data);
321
+ },
322
+ onChange: (data) => {
323
+ if (!existsSync(data))
324
+ textField.setError('Path not exist');
325
+ else
326
+ textField.setError('');
327
+ },
328
+ },
329
+ });
330
+ };
331
+ const moveItemToTrash = () => {
332
+ if (index < 0 || index >= filesList.length)
333
+ return;
334
+ const node = filesList[index];
335
+ if (node.type === 'DRIVE')
336
+ return;
337
+ inputCapture.addCallback(async (key) => {
338
+ if (key !== 'y')
339
+ return;
340
+ isInputEnable.current = false;
341
+ alert.alertControlled({
342
+ kind: 'INFO',
343
+ message: 'Moving item to trash...',
344
+ });
345
+ try {
346
+ await operations.removeNode(node);
347
+ alert.setAlert({
348
+ message: 'Moved successfull',
349
+ kind: 'SUCCESS',
350
+ });
351
+ eventHandler.publish(createNodeWrittenEvent());
352
+ }
353
+ catch (error) {
354
+ alert.setAlert({
355
+ kind: 'ERR',
356
+ message: error.message,
357
+ });
358
+ }
359
+ isInputEnable.current = true;
360
+ }, 'Do you want to move this item to trash? Y/n');
361
+ };
362
+ const setGlobPattern = () => {
363
+ if (filesList.some((e) => e.type === 'DRIVE'))
364
+ return;
365
+ textField.addCallback({
366
+ placeHolder: 'Add glob pattern to search...',
367
+ callback: {
368
+ onChange() { },
369
+ onSuccess(data) {
370
+ files.selectByGlobPattern(data);
371
+ },
372
+ },
373
+ });
374
+ };
375
+ useInput((input, key) => {
376
+ if (!isInputEnable.current ||
377
+ inputCapture.isInputEnabled ||
378
+ textField.isInputEnabled ||
379
+ isBookmarkEnabled)
380
+ return;
381
+ if (key.ctrl && key.upArrow)
382
+ files.gotToUpper();
383
+ else if (key.ctrl && key.leftArrow)
384
+ files.popHistory();
385
+ else if (key.ctrl && key.rightArrow)
386
+ files.forwardHistory();
387
+ else if (key.upArrow)
388
+ moveUpArrow();
389
+ else if (key.downArrow)
390
+ moveDownArrow();
391
+ else if (key.ctrl && input === 'd')
392
+ files.cleanNodeSelected();
393
+ else if (input === 'S' && key.shift)
394
+ addToBookmark();
395
+ else if (input === 'i')
396
+ selectToDetails();
397
+ else if (input === 'a')
398
+ createDir();
399
+ else if (input === 'l' && key.ctrl)
400
+ setPath();
401
+ else if (input === 'R' && key.shift)
402
+ renameItem();
403
+ else if (input === 'd')
404
+ moveItemToTrash();
405
+ else if (input === 'D' && key.shift)
406
+ deleteItem();
407
+ else if (input === 'p')
408
+ executePaste(false);
409
+ else if (input === 'P' && key.shift)
410
+ executePaste(true);
411
+ else if (key.shift && input === 'T')
412
+ openDirInNewTab();
413
+ else if (input === 'C' && key.shift)
414
+ setCut();
415
+ else if (input === 'c')
416
+ setCopy();
417
+ else if (input === 'r')
418
+ files.refresh();
419
+ else if (key.shift && key.rightArrow)
420
+ files.unSelectAll();
421
+ else if (key.rightArrow)
422
+ toggleSelectItem();
423
+ else if (key.shift && input === 'A')
424
+ files.selectAll();
425
+ else if (key.shift && input === 'I')
426
+ files.inevertSelection();
427
+ else if (key.return)
428
+ selectItem();
429
+ else if (key.escape)
430
+ clipboard.removeItem();
431
+ else if (input === ';')
432
+ runCommandAsync();
433
+ else if (input === ':')
434
+ runCommandSync();
435
+ else if (input === 'y')
436
+ copyNodePathToClipboard();
437
+ else if (input === 'Y' && key.shift)
438
+ copyPathToClipboard();
439
+ else if (input === 'g')
440
+ setGlobPattern();
441
+ });
442
+ if (files.isLoading.value)
443
+ return (React.createElement(Box, { width: "100%", alignItems: "center" },
444
+ React.createElement(Text, null, "Loading...")));
445
+ if (files.isError.value)
446
+ return (React.createElement(Box, { width: "100%", alignItems: "center" },
447
+ React.createElement(Text, null, files.isError.value.message)));
448
+ const selections = files.selections.value;
449
+ return (React.createElement(React.Fragment, null,
450
+ React.createElement(Box, { height: "100%", flexDirection: "row", borderStyle: "round" },
451
+ React.createElement(Box, { overflowY: "hidden", flexDirection: "column", width: "100%", height: "100%" },
452
+ React.createElement(Box, { width: "100%", borderStyle: "double" },
453
+ React.createElement(Text, null, files.path.value)),
454
+ React.createElement(NodeList, { nodes: files.files.value, index: index, isTabs: tabs.tabs.value.length > 1, selections: files.selections.value })),
455
+ files.selectedNode.value && (React.createElement(NodeDetails, { node: files.selectedNode.value })))));
456
+ }
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export const Loading = (props) => {
3
+ return React.createElement(React.Fragment, null, props.isloading ? props.fallback : props.children);
4
+ };