@noya-app/noya-file-explorer 0.0.2
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/.eslintrc.js +11 -0
- package/.turbo/turbo-build.log +24 -0
- package/CHANGELOG.md +14 -0
- package/README.md +3 -0
- package/dist/index.css +1811 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +23279 -0
- package/dist/index.d.ts +23279 -0
- package/dist/index.js +1854 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1857 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +37 -0
- package/src/MediaCollection.tsx +839 -0
- package/src/__tests__/deleteMediaItems.test.ts +125 -0
- package/src/__tests__/getDepthMap.test.ts +84 -0
- package/src/__tests__/getParentDirectories.test.ts +68 -0
- package/src/__tests__/getVisibleItems.test.ts +184 -0
- package/src/__tests__/moveMediaInsideFolder.test.ts +348 -0
- package/src/__tests__/movePathsIntoTarget.test.ts +229 -0
- package/src/__tests__/moveUpAFolder.test.ts +179 -0
- package/src/__tests__/updateExpandedMap.test.ts +157 -0
- package/src/__tests__/validateMediaItemRename.test.ts +200 -0
- package/src/index.css +1 -0
- package/src/index.ts +4 -0
- package/src/utils/files.ts +274 -0
- package/src/utils/mediaItemTree.ts +110 -0
- package/tsconfig.json +3 -0
- package/tsup.config.ts +13 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1857 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
+
mod
|
|
25
|
+
));
|
|
26
|
+
|
|
27
|
+
// ../../node_modules/tree-visit/lib/access.js
|
|
28
|
+
var require_access = __commonJS({
|
|
29
|
+
"../../node_modules/tree-visit/lib/access.js"(exports) {
|
|
30
|
+
"use strict";
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.accessPath = exports.access = void 0;
|
|
33
|
+
function access(node, indexPath, options) {
|
|
34
|
+
if (options.includeTraversalContext) {
|
|
35
|
+
const accessed = accessPath(node, indexPath, options);
|
|
36
|
+
return accessed[accessed.length - 1];
|
|
37
|
+
}
|
|
38
|
+
let path4 = indexPath.slice();
|
|
39
|
+
while (path4.length > 0) {
|
|
40
|
+
let index = path4.shift();
|
|
41
|
+
node = options.getChildren(node, path4)[index];
|
|
42
|
+
}
|
|
43
|
+
return node;
|
|
44
|
+
}
|
|
45
|
+
exports.access = access;
|
|
46
|
+
function accessPath(node, indexPath, options) {
|
|
47
|
+
let path4 = indexPath.slice();
|
|
48
|
+
let result = [node];
|
|
49
|
+
while (path4.length > 0) {
|
|
50
|
+
let index = path4.shift();
|
|
51
|
+
const context = options.includeTraversalContext ? {
|
|
52
|
+
getRoot: () => result[0],
|
|
53
|
+
getParent: () => result[result.length - 2],
|
|
54
|
+
getAncestors: () => result.slice(0, -1)
|
|
55
|
+
} : void 0;
|
|
56
|
+
node = options.getChildren(node, path4, context)[index];
|
|
57
|
+
result.push(node);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
exports.accessPath = accessPath;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// ../../node_modules/tree-visit/lib/sort.js
|
|
66
|
+
var require_sort = __commonJS({
|
|
67
|
+
"../../node_modules/tree-visit/lib/sort.js"(exports) {
|
|
68
|
+
"use strict";
|
|
69
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
70
|
+
exports.sortPaths = exports.comparePathsByComponent = void 0;
|
|
71
|
+
function comparePathsByComponent(a, b) {
|
|
72
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
|
73
|
+
if (a[i] < b[i])
|
|
74
|
+
return -1;
|
|
75
|
+
if (a[i] > b[i])
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
return a.length - b.length;
|
|
79
|
+
}
|
|
80
|
+
exports.comparePathsByComponent = comparePathsByComponent;
|
|
81
|
+
function sortPaths(indexPaths) {
|
|
82
|
+
return [...indexPaths].sort(comparePathsByComponent);
|
|
83
|
+
}
|
|
84
|
+
exports.sortPaths = sortPaths;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// ../../node_modules/tree-visit/lib/ancestors.js
|
|
89
|
+
var require_ancestors = __commonJS({
|
|
90
|
+
"../../node_modules/tree-visit/lib/ancestors.js"(exports) {
|
|
91
|
+
"use strict";
|
|
92
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
93
|
+
exports.ancestorPaths = void 0;
|
|
94
|
+
var sort_1 = require_sort();
|
|
95
|
+
function ancestorPaths2(paths, options) {
|
|
96
|
+
var _a;
|
|
97
|
+
const result = /* @__PURE__ */ new Map();
|
|
98
|
+
const compare = (_a = options === null || options === void 0 ? void 0 : options.compare) !== null && _a !== void 0 ? _a : sort_1.comparePathsByComponent;
|
|
99
|
+
const sortedIndexPaths = paths.sort(compare);
|
|
100
|
+
for (const indexPath of sortedIndexPaths) {
|
|
101
|
+
const foundParent = indexPath.some((_, index) => {
|
|
102
|
+
const parentKey = indexPath.slice(0, index).join();
|
|
103
|
+
return result.has(parentKey);
|
|
104
|
+
});
|
|
105
|
+
if (foundParent)
|
|
106
|
+
continue;
|
|
107
|
+
result.set(indexPath.join(), indexPath);
|
|
108
|
+
}
|
|
109
|
+
return Array.from(result.values());
|
|
110
|
+
}
|
|
111
|
+
exports.ancestorPaths = ancestorPaths2;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// ../../node_modules/tree-visit/lib/diagram/boxDiagram.js
|
|
116
|
+
var require_boxDiagram = __commonJS({
|
|
117
|
+
"../../node_modules/tree-visit/lib/diagram/boxDiagram.js"(exports) {
|
|
118
|
+
"use strict";
|
|
119
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
120
|
+
exports.boxDiagram = void 0;
|
|
121
|
+
var BoxDrawing;
|
|
122
|
+
(function(BoxDrawing2) {
|
|
123
|
+
BoxDrawing2["TopLeft"] = "\u250C";
|
|
124
|
+
BoxDrawing2["TopRight"] = "\u2510";
|
|
125
|
+
BoxDrawing2["BottomLeft"] = "\u2514";
|
|
126
|
+
BoxDrawing2["BottomRight"] = "\u2518";
|
|
127
|
+
BoxDrawing2["Horizontal"] = "\u2500";
|
|
128
|
+
BoxDrawing2["Vertical"] = "\u2502";
|
|
129
|
+
BoxDrawing2["BottomConnectorDown"] = "\u252C";
|
|
130
|
+
BoxDrawing2["BottomConnectorUp"] = "\u2534";
|
|
131
|
+
BoxDrawing2["TopConnectorUp"] = "\u2534";
|
|
132
|
+
})(BoxDrawing || (BoxDrawing = {}));
|
|
133
|
+
function wrapLabelInBox(label) {
|
|
134
|
+
const lines = label.split("\n");
|
|
135
|
+
const length = Math.max(...lines.map((line) => line.length));
|
|
136
|
+
const horizontalMargin = 1;
|
|
137
|
+
const width = length + horizontalMargin * 2 + 2;
|
|
138
|
+
const height = 2 + lines.length;
|
|
139
|
+
const diagram = [
|
|
140
|
+
[
|
|
141
|
+
BoxDrawing.TopLeft,
|
|
142
|
+
BoxDrawing.Horizontal.repeat(length + horizontalMargin * 2),
|
|
143
|
+
BoxDrawing.TopRight
|
|
144
|
+
],
|
|
145
|
+
...lines.map((line) => [
|
|
146
|
+
BoxDrawing.Vertical,
|
|
147
|
+
" ".repeat(horizontalMargin),
|
|
148
|
+
line + (line.length < length ? " ".repeat(length - line.length) : ""),
|
|
149
|
+
" ".repeat(horizontalMargin),
|
|
150
|
+
BoxDrawing.Vertical
|
|
151
|
+
]),
|
|
152
|
+
[
|
|
153
|
+
BoxDrawing.BottomLeft,
|
|
154
|
+
BoxDrawing.Horizontal.repeat(length + horizontalMargin * 2),
|
|
155
|
+
BoxDrawing.BottomRight
|
|
156
|
+
]
|
|
157
|
+
];
|
|
158
|
+
return {
|
|
159
|
+
width,
|
|
160
|
+
height,
|
|
161
|
+
contents: diagram.map((parts) => parts.join(""))
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function mergeBoxesHorizontal(boxes) {
|
|
165
|
+
const horizontalMargin = 1;
|
|
166
|
+
if (boxes.length === 0) {
|
|
167
|
+
throw new Error("Can't merge empty array of boxes");
|
|
168
|
+
}
|
|
169
|
+
return boxes.slice(1).reduce((result, box) => {
|
|
170
|
+
const height = Math.max(result.height, box.height);
|
|
171
|
+
const width = result.width + horizontalMargin + box.width;
|
|
172
|
+
const contents = [];
|
|
173
|
+
for (let i = 0; i < height; i++) {
|
|
174
|
+
contents.push((result.contents[i] || " ".repeat(result.width)) + " ".repeat(horizontalMargin) + (box.contents[i] || " ".repeat(box.width)));
|
|
175
|
+
}
|
|
176
|
+
return { height, width, contents: centerBlock(contents, width) };
|
|
177
|
+
}, boxes[0]);
|
|
178
|
+
}
|
|
179
|
+
function mergeBoxesVertical(boxes) {
|
|
180
|
+
const verticalMargin = 1;
|
|
181
|
+
if (boxes.length === 0) {
|
|
182
|
+
throw new Error("Can't merge empty array of boxes");
|
|
183
|
+
}
|
|
184
|
+
const width = Math.max(...boxes.map((box) => box.width));
|
|
185
|
+
return boxes.slice(1).reduce((result, box) => {
|
|
186
|
+
const height = result.height + verticalMargin + box.height;
|
|
187
|
+
const contents = [];
|
|
188
|
+
for (let i = 0; i < height; i++) {
|
|
189
|
+
if (i < result.height) {
|
|
190
|
+
contents.push(result.contents[i]);
|
|
191
|
+
} else if (i === result.height) {
|
|
192
|
+
contents.push(" ".repeat(width));
|
|
193
|
+
} else {
|
|
194
|
+
contents.push(box.contents[i - result.height - 1]);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return { height, width, contents: centerBlock(contents, width) };
|
|
198
|
+
}, boxes[0]);
|
|
199
|
+
}
|
|
200
|
+
function nodeDiagram(node, indexPath, options) {
|
|
201
|
+
const label = options.getLabel(node, indexPath);
|
|
202
|
+
const box = wrapLabelInBox(label);
|
|
203
|
+
const children = options.getChildren(node, indexPath);
|
|
204
|
+
if (children.length === 0)
|
|
205
|
+
return box;
|
|
206
|
+
const childBoxes = children.map((child, index) => {
|
|
207
|
+
const childBox = nodeDiagram(child, [...indexPath, index], options);
|
|
208
|
+
childBox.contents[0] = insertSubstring(childBox.contents[0], centerIndex(childBox.contents[0].length), BoxDrawing.TopConnectorUp);
|
|
209
|
+
return childBox;
|
|
210
|
+
});
|
|
211
|
+
const result = mergeBoxesVertical([box, mergeBoxesHorizontal(childBoxes)]);
|
|
212
|
+
const contents = result.contents;
|
|
213
|
+
const mid = centerIndex(result.width);
|
|
214
|
+
contents[box.height - 1] = insertSubstring(contents[box.height - 1], mid, BoxDrawing.BottomConnectorDown);
|
|
215
|
+
let min = contents[box.height + 1].indexOf(BoxDrawing.TopConnectorUp);
|
|
216
|
+
let max = contents[box.height + 1].lastIndexOf(BoxDrawing.TopConnectorUp);
|
|
217
|
+
for (let i = min; i <= max; i++) {
|
|
218
|
+
let character;
|
|
219
|
+
if (i === mid) {
|
|
220
|
+
character = childBoxes.length > 1 ? BoxDrawing.BottomConnectorUp : BoxDrawing.Vertical;
|
|
221
|
+
} else if (i === min) {
|
|
222
|
+
character = BoxDrawing.TopLeft;
|
|
223
|
+
} else if (i === max) {
|
|
224
|
+
character = BoxDrawing.TopRight;
|
|
225
|
+
} else {
|
|
226
|
+
character = BoxDrawing.Horizontal;
|
|
227
|
+
}
|
|
228
|
+
result.contents[box.height] = insertSubstring(result.contents[box.height], i, character);
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
function boxDiagram(node, options) {
|
|
233
|
+
return nodeDiagram(node, [], options).contents.join("\n");
|
|
234
|
+
}
|
|
235
|
+
exports.boxDiagram = boxDiagram;
|
|
236
|
+
function centerIndex(width) {
|
|
237
|
+
return Math.floor(width / 2);
|
|
238
|
+
}
|
|
239
|
+
function centerLine(line, width) {
|
|
240
|
+
const remainder = width - line.length;
|
|
241
|
+
if (remainder <= 0)
|
|
242
|
+
return line;
|
|
243
|
+
const prefixLength = centerIndex(remainder);
|
|
244
|
+
const suffixLength = centerIndex(remainder);
|
|
245
|
+
const result = " ".repeat(prefixLength) + line + " ".repeat(suffixLength);
|
|
246
|
+
return prefixLength + suffixLength + result.length < width ? result + " " : result;
|
|
247
|
+
}
|
|
248
|
+
function centerBlock(lines, width) {
|
|
249
|
+
return lines.map((line) => centerLine(line, width));
|
|
250
|
+
}
|
|
251
|
+
function insertSubstring(string, index, substring) {
|
|
252
|
+
if (index > string.length - 1)
|
|
253
|
+
return string;
|
|
254
|
+
return string.substring(0, index) + substring + string.substring(index + 1);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// ../../node_modules/tree-visit/lib/diagram/directoryDiagram.js
|
|
260
|
+
var require_directoryDiagram = __commonJS({
|
|
261
|
+
"../../node_modules/tree-visit/lib/diagram/directoryDiagram.js"(exports) {
|
|
262
|
+
"use strict";
|
|
263
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
264
|
+
exports.prefixBlock = exports.isMultiline = exports.directoryDiagram = void 0;
|
|
265
|
+
var LinePrefix;
|
|
266
|
+
(function(LinePrefix2) {
|
|
267
|
+
LinePrefix2["Child"] = "\u251C\u2500\u2500 ";
|
|
268
|
+
LinePrefix2["LastChild"] = "\u2514\u2500\u2500 ";
|
|
269
|
+
LinePrefix2["NestedChild"] = "\u2502 ";
|
|
270
|
+
LinePrefix2["LastNestedChild"] = " ";
|
|
271
|
+
})(LinePrefix || (LinePrefix = {}));
|
|
272
|
+
function nodeDiagram(node, indexPath, options) {
|
|
273
|
+
const label = options.getLabel(node, indexPath);
|
|
274
|
+
const depth = indexPath.length;
|
|
275
|
+
let rootLine = { label, depth, prefix: "", multilinePrefix: "" };
|
|
276
|
+
const children = options.getChildren(node, indexPath);
|
|
277
|
+
if (children.length === 0)
|
|
278
|
+
return [rootLine];
|
|
279
|
+
if (options.flattenSingleChildNodes && children.length === 1 && !isMultiline(label)) {
|
|
280
|
+
const [line] = nodeDiagram(children[0], [...indexPath, 0], options);
|
|
281
|
+
const hideRoot = indexPath.length === 0 && label === "";
|
|
282
|
+
rootLine.label = hideRoot ? `/ ${line.label}` : `${rootLine.label} / ${line.label}`;
|
|
283
|
+
return [rootLine];
|
|
284
|
+
}
|
|
285
|
+
const nestedLines = children.flatMap((file, index, array) => {
|
|
286
|
+
const childIsLast = index === array.length - 1;
|
|
287
|
+
const childLines = nodeDiagram(file, [...indexPath, index], options);
|
|
288
|
+
const childPrefix = childIsLast ? LinePrefix.LastChild : LinePrefix.Child;
|
|
289
|
+
const childMultilinePrefix = childIsLast ? LinePrefix.LastNestedChild : LinePrefix.NestedChild;
|
|
290
|
+
childLines.forEach((line) => {
|
|
291
|
+
if (line.depth === depth + 1) {
|
|
292
|
+
line.prefix = childPrefix + line.prefix;
|
|
293
|
+
line.multilinePrefix = childMultilinePrefix + line.multilinePrefix;
|
|
294
|
+
} else if (childIsLast) {
|
|
295
|
+
line.prefix = LinePrefix.LastNestedChild + line.prefix;
|
|
296
|
+
line.multilinePrefix = LinePrefix.LastNestedChild + line.multilinePrefix;
|
|
297
|
+
} else {
|
|
298
|
+
line.prefix = LinePrefix.NestedChild + line.prefix;
|
|
299
|
+
line.multilinePrefix = LinePrefix.NestedChild + line.multilinePrefix;
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
return childLines;
|
|
303
|
+
});
|
|
304
|
+
return [rootLine, ...nestedLines];
|
|
305
|
+
}
|
|
306
|
+
function directoryDiagram(node, options) {
|
|
307
|
+
const lines = nodeDiagram(node, [], options);
|
|
308
|
+
const strings = lines.map((line) => prefixBlock(line.label, line.prefix, line.multilinePrefix));
|
|
309
|
+
return strings.join("\n");
|
|
310
|
+
}
|
|
311
|
+
exports.directoryDiagram = directoryDiagram;
|
|
312
|
+
function isMultiline(line) {
|
|
313
|
+
return line.includes("\n");
|
|
314
|
+
}
|
|
315
|
+
exports.isMultiline = isMultiline;
|
|
316
|
+
function prefixBlock(block, prefix, multilinePrefix) {
|
|
317
|
+
if (!isMultiline(block))
|
|
318
|
+
return prefix + block;
|
|
319
|
+
return block.split("\n").map((line, index) => (index === 0 ? prefix : multilinePrefix) + line).join("\n");
|
|
320
|
+
}
|
|
321
|
+
exports.prefixBlock = prefixBlock;
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// ../../node_modules/tree-visit/lib/diagram.js
|
|
326
|
+
var require_diagram = __commonJS({
|
|
327
|
+
"../../node_modules/tree-visit/lib/diagram.js"(exports) {
|
|
328
|
+
"use strict";
|
|
329
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
330
|
+
exports.diagram = void 0;
|
|
331
|
+
var boxDiagram_1 = require_boxDiagram();
|
|
332
|
+
var directoryDiagram_1 = require_directoryDiagram();
|
|
333
|
+
function diagram(node, options) {
|
|
334
|
+
if (options.type === "box") {
|
|
335
|
+
return (0, boxDiagram_1.boxDiagram)(node, options);
|
|
336
|
+
}
|
|
337
|
+
return (0, directoryDiagram_1.directoryDiagram)(node, options);
|
|
338
|
+
}
|
|
339
|
+
exports.diagram = diagram;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// ../../node_modules/tree-visit/lib/visit.js
|
|
344
|
+
var require_visit = __commonJS({
|
|
345
|
+
"../../node_modules/tree-visit/lib/visit.js"(exports) {
|
|
346
|
+
"use strict";
|
|
347
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
348
|
+
exports.visit = exports.STOP = exports.SKIP = void 0;
|
|
349
|
+
exports.SKIP = "skip";
|
|
350
|
+
exports.STOP = "stop";
|
|
351
|
+
function visit(node, options) {
|
|
352
|
+
const { onEnter, onLeave, getChildren, onDetectCycle, getIdentifier } = options;
|
|
353
|
+
let indexPath = [];
|
|
354
|
+
let stack = [{ node }];
|
|
355
|
+
const visited = onDetectCycle ? /* @__PURE__ */ new Set() : void 0;
|
|
356
|
+
const context = options.includeTraversalContext ? {
|
|
357
|
+
getRoot() {
|
|
358
|
+
return node;
|
|
359
|
+
},
|
|
360
|
+
getParent() {
|
|
361
|
+
var _a;
|
|
362
|
+
return (_a = stack[stack.length - 2]) === null || _a === void 0 ? void 0 : _a.node;
|
|
363
|
+
},
|
|
364
|
+
getAncestors() {
|
|
365
|
+
return stack.slice(0, -1).map((wrapper) => wrapper.node);
|
|
366
|
+
}
|
|
367
|
+
} : void 0;
|
|
368
|
+
const getIndexPath = options.reuseIndexPath ? () => indexPath : () => indexPath.slice();
|
|
369
|
+
while (stack.length > 0) {
|
|
370
|
+
let wrapper = stack[stack.length - 1];
|
|
371
|
+
if (wrapper.state === void 0) {
|
|
372
|
+
if (visited) {
|
|
373
|
+
const id = getIdentifier ? getIdentifier(wrapper.node) : wrapper.node;
|
|
374
|
+
if (visited.has(id)) {
|
|
375
|
+
const action = typeof onDetectCycle === "function" ? onDetectCycle(wrapper.node, getIndexPath(), context) : onDetectCycle;
|
|
376
|
+
if (action === "error") {
|
|
377
|
+
throw new Error("Cycle detected in tree");
|
|
378
|
+
} else {
|
|
379
|
+
wrapper.state = -1;
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
visited.add(id);
|
|
384
|
+
}
|
|
385
|
+
const enterResult = onEnter === null || onEnter === void 0 ? void 0 : onEnter(wrapper.node, getIndexPath());
|
|
386
|
+
if (enterResult === exports.STOP)
|
|
387
|
+
return;
|
|
388
|
+
wrapper.state = enterResult === exports.SKIP ? -1 : 0;
|
|
389
|
+
}
|
|
390
|
+
const children = wrapper.children || getChildren(wrapper.node, getIndexPath(), context);
|
|
391
|
+
if (!wrapper.children) {
|
|
392
|
+
wrapper.children = children;
|
|
393
|
+
}
|
|
394
|
+
if (wrapper.state !== -1) {
|
|
395
|
+
if (wrapper.state < children.length) {
|
|
396
|
+
let currentIndex = wrapper.state;
|
|
397
|
+
indexPath.push(currentIndex);
|
|
398
|
+
stack.push({ node: children[currentIndex] });
|
|
399
|
+
wrapper.state = currentIndex + 1;
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
const leaveResult = onLeave === null || onLeave === void 0 ? void 0 : onLeave(wrapper.node, getIndexPath());
|
|
403
|
+
if (leaveResult === exports.STOP)
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
if (visited) {
|
|
407
|
+
const id = getIdentifier ? getIdentifier(wrapper.node) : wrapper.node;
|
|
408
|
+
visited.delete(id);
|
|
409
|
+
}
|
|
410
|
+
indexPath.pop();
|
|
411
|
+
stack.pop();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
exports.visit = visit;
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// ../../node_modules/tree-visit/lib/find.js
|
|
419
|
+
var require_find = __commonJS({
|
|
420
|
+
"../../node_modules/tree-visit/lib/find.js"(exports) {
|
|
421
|
+
"use strict";
|
|
422
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
423
|
+
exports.findAllIndexPaths = exports.findIndexPath = exports.findAll = exports.find = void 0;
|
|
424
|
+
var visit_1 = require_visit();
|
|
425
|
+
function find(node, options) {
|
|
426
|
+
let found;
|
|
427
|
+
(0, visit_1.visit)(node, Object.assign(Object.assign({}, options), { onEnter: (child, indexPath) => {
|
|
428
|
+
if (options.predicate(child, indexPath)) {
|
|
429
|
+
found = child;
|
|
430
|
+
return visit_1.STOP;
|
|
431
|
+
}
|
|
432
|
+
} }));
|
|
433
|
+
return found;
|
|
434
|
+
}
|
|
435
|
+
exports.find = find;
|
|
436
|
+
function findAll(node, options) {
|
|
437
|
+
let found = [];
|
|
438
|
+
(0, visit_1.visit)(node, {
|
|
439
|
+
onEnter: (child, indexPath) => {
|
|
440
|
+
if (options.predicate(child, indexPath)) {
|
|
441
|
+
found.push(child);
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
getChildren: options.getChildren
|
|
445
|
+
});
|
|
446
|
+
return found;
|
|
447
|
+
}
|
|
448
|
+
exports.findAll = findAll;
|
|
449
|
+
function findIndexPath(node, options) {
|
|
450
|
+
let found;
|
|
451
|
+
(0, visit_1.visit)(node, {
|
|
452
|
+
onEnter: (child, indexPath) => {
|
|
453
|
+
if (options.predicate(child, indexPath)) {
|
|
454
|
+
found = [...indexPath];
|
|
455
|
+
return visit_1.STOP;
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
getChildren: options.getChildren
|
|
459
|
+
});
|
|
460
|
+
return found;
|
|
461
|
+
}
|
|
462
|
+
exports.findIndexPath = findIndexPath;
|
|
463
|
+
function findAllIndexPaths(node, options) {
|
|
464
|
+
let found = [];
|
|
465
|
+
(0, visit_1.visit)(node, {
|
|
466
|
+
onEnter: (child, indexPath) => {
|
|
467
|
+
if (options.predicate(child, indexPath)) {
|
|
468
|
+
found.push([...indexPath]);
|
|
469
|
+
}
|
|
470
|
+
},
|
|
471
|
+
getChildren: options.getChildren
|
|
472
|
+
});
|
|
473
|
+
return found;
|
|
474
|
+
}
|
|
475
|
+
exports.findAllIndexPaths = findAllIndexPaths;
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// ../../node_modules/tree-visit/lib/reduce.js
|
|
480
|
+
var require_reduce = __commonJS({
|
|
481
|
+
"../../node_modules/tree-visit/lib/reduce.js"(exports) {
|
|
482
|
+
"use strict";
|
|
483
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
484
|
+
exports.reduce = void 0;
|
|
485
|
+
var visit_1 = require_visit();
|
|
486
|
+
function reduce(node, options) {
|
|
487
|
+
let result = options.initialResult;
|
|
488
|
+
(0, visit_1.visit)(node, Object.assign(Object.assign({}, options), { onEnter: (child, indexPath) => {
|
|
489
|
+
result = options.nextResult(result, child, indexPath);
|
|
490
|
+
} }));
|
|
491
|
+
return result;
|
|
492
|
+
}
|
|
493
|
+
exports.reduce = reduce;
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// ../../node_modules/tree-visit/lib/flat.js
|
|
498
|
+
var require_flat = __commonJS({
|
|
499
|
+
"../../node_modules/tree-visit/lib/flat.js"(exports) {
|
|
500
|
+
"use strict";
|
|
501
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
502
|
+
exports.flat = void 0;
|
|
503
|
+
var reduce_1 = require_reduce();
|
|
504
|
+
function flat(node, options) {
|
|
505
|
+
return (0, reduce_1.reduce)(node, Object.assign(Object.assign({}, options), { initialResult: [], nextResult: (result, child) => {
|
|
506
|
+
result.push(child);
|
|
507
|
+
return result;
|
|
508
|
+
} }));
|
|
509
|
+
}
|
|
510
|
+
exports.flat = flat;
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
// ../../node_modules/tree-visit/lib/flatMap.js
|
|
515
|
+
var require_flatMap = __commonJS({
|
|
516
|
+
"../../node_modules/tree-visit/lib/flatMap.js"(exports) {
|
|
517
|
+
"use strict";
|
|
518
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
519
|
+
exports.flatMap = void 0;
|
|
520
|
+
var reduce_1 = require_reduce();
|
|
521
|
+
function flatMap(node, options) {
|
|
522
|
+
return (0, reduce_1.reduce)(node, Object.assign(Object.assign({}, options), { initialResult: [], nextResult: (result, child, indexPath) => {
|
|
523
|
+
result.push(...options.transform(child, indexPath));
|
|
524
|
+
return result;
|
|
525
|
+
} }));
|
|
526
|
+
}
|
|
527
|
+
exports.flatMap = flatMap;
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// ../../node_modules/tree-visit/lib/map.js
|
|
532
|
+
var require_map = __commonJS({
|
|
533
|
+
"../../node_modules/tree-visit/lib/map.js"(exports) {
|
|
534
|
+
"use strict";
|
|
535
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
536
|
+
exports.map = void 0;
|
|
537
|
+
var visit_1 = require_visit();
|
|
538
|
+
function map(node, options) {
|
|
539
|
+
const childrenMap = {};
|
|
540
|
+
(0, visit_1.visit)(node, Object.assign(Object.assign({}, options), { onLeave: (child, indexPath) => {
|
|
541
|
+
var _a, _b;
|
|
542
|
+
const keyIndexPath = [0, ...indexPath];
|
|
543
|
+
const key = keyIndexPath.join();
|
|
544
|
+
const transformed = options.transform(child, (_a = childrenMap[key]) !== null && _a !== void 0 ? _a : [], indexPath);
|
|
545
|
+
const parentKey = keyIndexPath.slice(0, -1).join();
|
|
546
|
+
const parentChildren = (_b = childrenMap[parentKey]) !== null && _b !== void 0 ? _b : [];
|
|
547
|
+
parentChildren.push(transformed);
|
|
548
|
+
childrenMap[parentKey] = parentChildren;
|
|
549
|
+
} }));
|
|
550
|
+
return childrenMap[""][0];
|
|
551
|
+
}
|
|
552
|
+
exports.map = map;
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
// ../../node_modules/tree-visit/lib/operation.js
|
|
557
|
+
var require_operation = __commonJS({
|
|
558
|
+
"../../node_modules/tree-visit/lib/operation.js"(exports) {
|
|
559
|
+
"use strict";
|
|
560
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
561
|
+
exports.splice = exports.applyOperations = exports.getReplaceOperations = exports.getRemovalOperations = exports.getInsertionOperations = exports.replaceOperation = exports.removeOperation = exports.insertOperation = void 0;
|
|
562
|
+
var ancestors_1 = require_ancestors();
|
|
563
|
+
var map_1 = require_map();
|
|
564
|
+
function insertOperation(index, nodes) {
|
|
565
|
+
return {
|
|
566
|
+
type: "insert",
|
|
567
|
+
index,
|
|
568
|
+
nodes
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
exports.insertOperation = insertOperation;
|
|
572
|
+
function removeOperation(indexes) {
|
|
573
|
+
return {
|
|
574
|
+
type: "remove",
|
|
575
|
+
indexes
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
exports.removeOperation = removeOperation;
|
|
579
|
+
function replaceOperation() {
|
|
580
|
+
return {
|
|
581
|
+
type: "replace"
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
exports.replaceOperation = replaceOperation;
|
|
585
|
+
function splitIndexPath(indexPath) {
|
|
586
|
+
return [indexPath.slice(0, -1), indexPath[indexPath.length - 1]];
|
|
587
|
+
}
|
|
588
|
+
function getInsertionOperations(indexPath, nodes, operations = /* @__PURE__ */ new Map()) {
|
|
589
|
+
var _a;
|
|
590
|
+
const [parentIndexPath, index] = splitIndexPath(indexPath);
|
|
591
|
+
for (let i = parentIndexPath.length - 1; i >= 0; i--) {
|
|
592
|
+
const parentKey = parentIndexPath.slice(0, i).join();
|
|
593
|
+
switch ((_a = operations.get(parentKey)) === null || _a === void 0 ? void 0 : _a.type) {
|
|
594
|
+
case "remove":
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
operations.set(parentKey, replaceOperation());
|
|
598
|
+
}
|
|
599
|
+
const operation = operations.get(parentIndexPath.join());
|
|
600
|
+
switch (operation === null || operation === void 0 ? void 0 : operation.type) {
|
|
601
|
+
case "remove":
|
|
602
|
+
operations.set(parentIndexPath.join(), {
|
|
603
|
+
type: "removeThenInsert",
|
|
604
|
+
removeIndexes: operation.indexes,
|
|
605
|
+
insertIndex: index,
|
|
606
|
+
insertNodes: nodes
|
|
607
|
+
});
|
|
608
|
+
break;
|
|
609
|
+
default:
|
|
610
|
+
operations.set(parentIndexPath.join(), insertOperation(index, nodes));
|
|
611
|
+
}
|
|
612
|
+
return operations;
|
|
613
|
+
}
|
|
614
|
+
exports.getInsertionOperations = getInsertionOperations;
|
|
615
|
+
function getRemovalOperations(indexPaths) {
|
|
616
|
+
var _a, _b;
|
|
617
|
+
const _ancestorIndexPaths = (0, ancestors_1.ancestorPaths)(indexPaths);
|
|
618
|
+
const indexesToRemove = /* @__PURE__ */ new Map();
|
|
619
|
+
for (const indexPath of _ancestorIndexPaths) {
|
|
620
|
+
const parentKey = indexPath.slice(0, -1).join();
|
|
621
|
+
const value = (_a = indexesToRemove.get(parentKey)) !== null && _a !== void 0 ? _a : [];
|
|
622
|
+
value.push(indexPath[indexPath.length - 1]);
|
|
623
|
+
indexesToRemove.set(parentKey, value);
|
|
624
|
+
}
|
|
625
|
+
const operations = /* @__PURE__ */ new Map();
|
|
626
|
+
for (const indexPath of _ancestorIndexPaths) {
|
|
627
|
+
for (let i = indexPath.length - 1; i >= 0; i--) {
|
|
628
|
+
const parentKey = indexPath.slice(0, i).join();
|
|
629
|
+
operations.set(parentKey, replaceOperation());
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
for (const indexPath of _ancestorIndexPaths) {
|
|
633
|
+
const parentKey = indexPath.slice(0, -1).join();
|
|
634
|
+
operations.set(parentKey, removeOperation((_b = indexesToRemove.get(parentKey)) !== null && _b !== void 0 ? _b : []));
|
|
635
|
+
}
|
|
636
|
+
return operations;
|
|
637
|
+
}
|
|
638
|
+
exports.getRemovalOperations = getRemovalOperations;
|
|
639
|
+
function getReplaceOperations(indexPath, node) {
|
|
640
|
+
const operations = /* @__PURE__ */ new Map();
|
|
641
|
+
const [parentIndexPath, index] = splitIndexPath(indexPath);
|
|
642
|
+
for (let i = parentIndexPath.length - 1; i >= 0; i--) {
|
|
643
|
+
const parentKey = parentIndexPath.slice(0, i).join();
|
|
644
|
+
operations.set(parentKey, replaceOperation());
|
|
645
|
+
}
|
|
646
|
+
operations.set(parentIndexPath.join(), {
|
|
647
|
+
type: "removeThenInsert",
|
|
648
|
+
removeIndexes: [index],
|
|
649
|
+
insertIndex: index,
|
|
650
|
+
insertNodes: [node]
|
|
651
|
+
});
|
|
652
|
+
return operations;
|
|
653
|
+
}
|
|
654
|
+
exports.getReplaceOperations = getReplaceOperations;
|
|
655
|
+
function applyOperations(node, operations, options) {
|
|
656
|
+
return (0, map_1.map)(node, Object.assign(Object.assign({}, options), {
|
|
657
|
+
// Avoid calling `getChildren` for every node in the tree.
|
|
658
|
+
// Return [] if we're just going to return the original node anyway.
|
|
659
|
+
getChildren: (node2, indexPath) => {
|
|
660
|
+
const key = indexPath.join();
|
|
661
|
+
const operation = operations.get(key);
|
|
662
|
+
switch (operation === null || operation === void 0 ? void 0 : operation.type) {
|
|
663
|
+
case "replace":
|
|
664
|
+
case "remove":
|
|
665
|
+
case "removeThenInsert":
|
|
666
|
+
case "insert":
|
|
667
|
+
return options.getChildren(node2, indexPath);
|
|
668
|
+
default:
|
|
669
|
+
return [];
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
transform: (node2, children, indexPath) => {
|
|
673
|
+
const key = indexPath.join();
|
|
674
|
+
const operation = operations.get(key);
|
|
675
|
+
switch (operation === null || operation === void 0 ? void 0 : operation.type) {
|
|
676
|
+
case "remove":
|
|
677
|
+
return options.create(node2, children.filter((_, index) => !operation.indexes.includes(index)), indexPath);
|
|
678
|
+
case "removeThenInsert":
|
|
679
|
+
const updatedChildren = children.filter((_, index) => !operation.removeIndexes.includes(index));
|
|
680
|
+
const adjustedIndex = operation.removeIndexes.reduce((index, removedIndex) => removedIndex < index ? index - 1 : index, operation.insertIndex);
|
|
681
|
+
return options.create(node2, splice(updatedChildren, adjustedIndex, 0, ...operation.insertNodes), indexPath);
|
|
682
|
+
case "insert":
|
|
683
|
+
return options.create(node2, splice(children, operation.index, 0, ...operation.nodes), indexPath);
|
|
684
|
+
case "replace":
|
|
685
|
+
return options.create(node2, children, indexPath);
|
|
686
|
+
default:
|
|
687
|
+
return node2;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}));
|
|
691
|
+
}
|
|
692
|
+
exports.applyOperations = applyOperations;
|
|
693
|
+
function splice(array, start, deleteCount, ...items) {
|
|
694
|
+
return [
|
|
695
|
+
...array.slice(0, start),
|
|
696
|
+
...items,
|
|
697
|
+
...array.slice(start + deleteCount)
|
|
698
|
+
];
|
|
699
|
+
}
|
|
700
|
+
exports.splice = splice;
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
// ../../node_modules/tree-visit/lib/insert.js
|
|
705
|
+
var require_insert = __commonJS({
|
|
706
|
+
"../../node_modules/tree-visit/lib/insert.js"(exports) {
|
|
707
|
+
"use strict";
|
|
708
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
709
|
+
exports.insert = void 0;
|
|
710
|
+
var operation_1 = require_operation();
|
|
711
|
+
function insert(node, options) {
|
|
712
|
+
const { nodes, at } = options;
|
|
713
|
+
if (at.length === 0) {
|
|
714
|
+
throw new Error(`Can't insert nodes at the root`);
|
|
715
|
+
}
|
|
716
|
+
const state = (0, operation_1.getInsertionOperations)(at, nodes);
|
|
717
|
+
return (0, operation_1.applyOperations)(node, state, options);
|
|
718
|
+
}
|
|
719
|
+
exports.insert = insert;
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
// ../../node_modules/tree-visit/lib/move.js
|
|
724
|
+
var require_move = __commonJS({
|
|
725
|
+
"../../node_modules/tree-visit/lib/move.js"(exports) {
|
|
726
|
+
"use strict";
|
|
727
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
728
|
+
exports.move = void 0;
|
|
729
|
+
var access_1 = require_access();
|
|
730
|
+
var ancestors_1 = require_ancestors();
|
|
731
|
+
var operation_1 = require_operation();
|
|
732
|
+
function move(node, options) {
|
|
733
|
+
if (options.indexPaths.length === 0)
|
|
734
|
+
return node;
|
|
735
|
+
for (const indexPath of options.indexPaths) {
|
|
736
|
+
if (indexPath.length === 0) {
|
|
737
|
+
throw new Error(`Can't move the root node`);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
if (options.to.length === 0) {
|
|
741
|
+
throw new Error(`Can't move nodes to the root`);
|
|
742
|
+
}
|
|
743
|
+
const _ancestorIndexPaths = (0, ancestors_1.ancestorPaths)(options.indexPaths);
|
|
744
|
+
const nodesToInsert = _ancestorIndexPaths.map((indexPath) => (0, access_1.access)(node, indexPath, options));
|
|
745
|
+
const operations = (0, operation_1.getInsertionOperations)(options.to, nodesToInsert, (0, operation_1.getRemovalOperations)(_ancestorIndexPaths));
|
|
746
|
+
return (0, operation_1.applyOperations)(node, operations, options);
|
|
747
|
+
}
|
|
748
|
+
exports.move = move;
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
// ../../node_modules/tree-visit/lib/remove.js
|
|
753
|
+
var require_remove = __commonJS({
|
|
754
|
+
"../../node_modules/tree-visit/lib/remove.js"(exports) {
|
|
755
|
+
"use strict";
|
|
756
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
757
|
+
exports.remove = void 0;
|
|
758
|
+
var operation_1 = require_operation();
|
|
759
|
+
function remove(node, options) {
|
|
760
|
+
if (options.indexPaths.length === 0)
|
|
761
|
+
return node;
|
|
762
|
+
for (const indexPath of options.indexPaths) {
|
|
763
|
+
if (indexPath.length === 0) {
|
|
764
|
+
throw new Error(`Can't remove the root node`);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
const operations = (0, operation_1.getRemovalOperations)(options.indexPaths);
|
|
768
|
+
return (0, operation_1.applyOperations)(node, operations, options);
|
|
769
|
+
}
|
|
770
|
+
exports.remove = remove;
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
// ../../node_modules/tree-visit/lib/replace.js
|
|
775
|
+
var require_replace = __commonJS({
|
|
776
|
+
"../../node_modules/tree-visit/lib/replace.js"(exports) {
|
|
777
|
+
"use strict";
|
|
778
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
779
|
+
exports.replace = void 0;
|
|
780
|
+
var operation_1 = require_operation();
|
|
781
|
+
function replace(node, options) {
|
|
782
|
+
if (options.at.length === 0)
|
|
783
|
+
return options.node;
|
|
784
|
+
const operations = (0, operation_1.getReplaceOperations)(options.at, options.node);
|
|
785
|
+
return (0, operation_1.applyOperations)(node, operations, options);
|
|
786
|
+
}
|
|
787
|
+
exports.replace = replace;
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
// ../../node_modules/tree-visit/lib/defineTree.js
|
|
792
|
+
var require_defineTree = __commonJS({
|
|
793
|
+
"../../node_modules/tree-visit/lib/defineTree.js"(exports) {
|
|
794
|
+
"use strict";
|
|
795
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
796
|
+
exports.defineTree = void 0;
|
|
797
|
+
var access_1 = require_access();
|
|
798
|
+
var diagram_1 = require_diagram();
|
|
799
|
+
var find_1 = require_find();
|
|
800
|
+
var flat_1 = require_flat();
|
|
801
|
+
var flatMap_1 = require_flatMap();
|
|
802
|
+
var insert_1 = require_insert();
|
|
803
|
+
var map_1 = require_map();
|
|
804
|
+
var move_1 = require_move();
|
|
805
|
+
var reduce_1 = require_reduce();
|
|
806
|
+
var remove_1 = require_remove();
|
|
807
|
+
var replace_1 = require_replace();
|
|
808
|
+
var visit_1 = require_visit();
|
|
809
|
+
var Tree = class _Tree {
|
|
810
|
+
constructor(getChildrenOrBaseOptions, appliedOptions) {
|
|
811
|
+
this.appliedOptions = appliedOptions;
|
|
812
|
+
this.getChildren = (node, indexPath, context) => {
|
|
813
|
+
return this._getChildren(node, indexPath, context);
|
|
814
|
+
};
|
|
815
|
+
this.mergeOptions = (options) => Object.assign(Object.assign(Object.assign({}, this.baseOptions), this.appliedOptions), options);
|
|
816
|
+
this.withOptions = (newOptions) => new _Tree(this.baseOptions, Object.assign(Object.assign({}, this.appliedOptions), newOptions));
|
|
817
|
+
this.access = (node, indexPath) => (0, access_1.access)(node, indexPath, this.mergeOptions({}));
|
|
818
|
+
this.accessPath = (node, indexPath) => (0, access_1.accessPath)(node, indexPath, this.mergeOptions({}));
|
|
819
|
+
this.diagram = (node, options) => typeof options === "function" ? (0, diagram_1.diagram)(node, this.mergeOptions({ getLabel: options })) : (0, diagram_1.diagram)(node, this.mergeOptions(options));
|
|
820
|
+
this.find = (node, predicateOrOptions) => typeof predicateOrOptions === "function" ? (0, find_1.find)(node, this.mergeOptions({ predicate: predicateOrOptions })) : (0, find_1.find)(node, this.mergeOptions(Object.assign({}, predicateOrOptions)));
|
|
821
|
+
this.findAll = (node, predicateOrOptions) => typeof predicateOrOptions === "function" ? (0, find_1.findAll)(node, this.mergeOptions({ predicate: predicateOrOptions })) : (0, find_1.findAll)(node, this.mergeOptions(Object.assign({}, predicateOrOptions)));
|
|
822
|
+
this.findIndexPath = (node, predicateOrOptions) => typeof predicateOrOptions === "function" ? (0, find_1.findIndexPath)(node, this.mergeOptions({ predicate: predicateOrOptions })) : (0, find_1.findIndexPath)(node, this.mergeOptions(Object.assign({}, predicateOrOptions)));
|
|
823
|
+
this.findAllIndexPaths = (node, predicateOrOptions) => typeof predicateOrOptions === "function" ? (0, find_1.findAllIndexPaths)(node, this.mergeOptions({ predicate: predicateOrOptions })) : (0, find_1.findAllIndexPaths)(node, this.mergeOptions(Object.assign({}, predicateOrOptions)));
|
|
824
|
+
this.flat = (node) => (0, flat_1.flat)(node, this.mergeOptions({}));
|
|
825
|
+
this.flatMap = (node, transform) => (0, flatMap_1.flatMap)(node, this.mergeOptions({ transform }));
|
|
826
|
+
this.reduce = (node, nextResult, initialResult) => (0, reduce_1.reduce)(node, this.mergeOptions({ nextResult, initialResult }));
|
|
827
|
+
this.map = (node, transform) => (0, map_1.map)(node, this.mergeOptions({ transform }));
|
|
828
|
+
this.visit = (node, onEnterOrOptions) => typeof onEnterOrOptions === "function" ? (0, visit_1.visit)(node, this.mergeOptions({ onEnter: onEnterOrOptions })) : (0, visit_1.visit)(node, this.mergeOptions(Object.assign({}, onEnterOrOptions)));
|
|
829
|
+
this.insert = (node, options) => (0, insert_1.insert)(node, this.mergeOptions(options));
|
|
830
|
+
this.remove = (node, options) => (0, remove_1.remove)(node, this.mergeOptions(options));
|
|
831
|
+
this.move = (node, options) => (0, move_1.move)(node, this.mergeOptions(options));
|
|
832
|
+
this.replace = (node, options) => (0, replace_1.replace)(node, this.mergeOptions(options));
|
|
833
|
+
this.baseOptions = typeof getChildrenOrBaseOptions === "function" ? { getChildren: getChildrenOrBaseOptions } : getChildrenOrBaseOptions;
|
|
834
|
+
this._getChildren = this.baseOptions.getChildren;
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
function defineTree2(getChildren) {
|
|
838
|
+
return new Tree(getChildren, {});
|
|
839
|
+
}
|
|
840
|
+
exports.defineTree = defineTree2;
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
// ../../node_modules/tree-visit/lib/indexPath.js
|
|
845
|
+
var require_indexPath = __commonJS({
|
|
846
|
+
"../../node_modules/tree-visit/lib/indexPath.js"(exports) {
|
|
847
|
+
"use strict";
|
|
848
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
|
|
852
|
+
// ../../node_modules/tree-visit/lib/options.js
|
|
853
|
+
var require_options = __commonJS({
|
|
854
|
+
"../../node_modules/tree-visit/lib/options.js"(exports) {
|
|
855
|
+
"use strict";
|
|
856
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
// ../../node_modules/tree-visit/lib/withOptions.js
|
|
861
|
+
var require_withOptions = __commonJS({
|
|
862
|
+
"../../node_modules/tree-visit/lib/withOptions.js"(exports) {
|
|
863
|
+
"use strict";
|
|
864
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
865
|
+
exports.withOptions = void 0;
|
|
866
|
+
var defineTree_1 = require_defineTree();
|
|
867
|
+
exports.withOptions = defineTree_1.defineTree;
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
// ../../node_modules/tree-visit/lib/index.js
|
|
872
|
+
var require_lib = __commonJS({
|
|
873
|
+
"../../node_modules/tree-visit/lib/index.js"(exports) {
|
|
874
|
+
"use strict";
|
|
875
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
876
|
+
if (k2 === void 0) k2 = k;
|
|
877
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() {
|
|
878
|
+
return m[k];
|
|
879
|
+
} });
|
|
880
|
+
} : function(o, m, k, k2) {
|
|
881
|
+
if (k2 === void 0) k2 = k;
|
|
882
|
+
o[k2] = m[k];
|
|
883
|
+
});
|
|
884
|
+
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
|
|
885
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
|
|
886
|
+
};
|
|
887
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
888
|
+
__exportStar(require_access(), exports);
|
|
889
|
+
__exportStar(require_ancestors(), exports);
|
|
890
|
+
__exportStar(require_defineTree(), exports);
|
|
891
|
+
__exportStar(require_diagram(), exports);
|
|
892
|
+
__exportStar(require_find(), exports);
|
|
893
|
+
__exportStar(require_flat(), exports);
|
|
894
|
+
__exportStar(require_flatMap(), exports);
|
|
895
|
+
__exportStar(require_indexPath(), exports);
|
|
896
|
+
__exportStar(require_insert(), exports);
|
|
897
|
+
__exportStar(require_map(), exports);
|
|
898
|
+
__exportStar(require_move(), exports);
|
|
899
|
+
__exportStar(require_options(), exports);
|
|
900
|
+
__exportStar(require_reduce(), exports);
|
|
901
|
+
__exportStar(require_remove(), exports);
|
|
902
|
+
__exportStar(require_replace(), exports);
|
|
903
|
+
__exportStar(require_sort(), exports);
|
|
904
|
+
__exportStar(require_visit(), exports);
|
|
905
|
+
__exportStar(require_withOptions(), exports);
|
|
906
|
+
}
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
// src/MediaCollection.tsx
|
|
910
|
+
import {
|
|
911
|
+
ActionMenu,
|
|
912
|
+
createSectionedMenu,
|
|
913
|
+
cssVars,
|
|
914
|
+
FileExplorerCollection,
|
|
915
|
+
FileExplorerDetail,
|
|
916
|
+
FileExplorerEmptyState,
|
|
917
|
+
FileExplorerLayout,
|
|
918
|
+
FileExplorerUploadButton,
|
|
919
|
+
MediaThumbnail
|
|
920
|
+
} from "@noya-app/noya-designsystem";
|
|
921
|
+
import {
|
|
922
|
+
DownloadIcon,
|
|
923
|
+
FolderIcon,
|
|
924
|
+
InputIcon,
|
|
925
|
+
OpenInNewWindowIcon,
|
|
926
|
+
ResetIcon,
|
|
927
|
+
TrashIcon,
|
|
928
|
+
UpdateIcon,
|
|
929
|
+
UploadIcon
|
|
930
|
+
} from "@noya-app/noya-icons";
|
|
931
|
+
import {
|
|
932
|
+
useAsset,
|
|
933
|
+
useAssetManager,
|
|
934
|
+
useAssets
|
|
935
|
+
} from "@noya-app/noya-multiplayer-react";
|
|
936
|
+
import { groupBy, isDeepEqual } from "@noya-app/noya-utils";
|
|
937
|
+
import {
|
|
938
|
+
downloadUrl,
|
|
939
|
+
memoGeneric,
|
|
940
|
+
useControlledOrUncontrolled
|
|
941
|
+
} from "@noya-app/react-utils";
|
|
942
|
+
import { fileOpen } from "browser-fs-access";
|
|
943
|
+
import {
|
|
944
|
+
forwardRef,
|
|
945
|
+
memo,
|
|
946
|
+
useCallback,
|
|
947
|
+
useEffect,
|
|
948
|
+
useImperativeHandle,
|
|
949
|
+
useMemo,
|
|
950
|
+
useRef,
|
|
951
|
+
useState
|
|
952
|
+
} from "react";
|
|
953
|
+
|
|
954
|
+
// src/utils/mediaItemTree.ts
|
|
955
|
+
var import_tree_visit = __toESM(require_lib());
|
|
956
|
+
import { uuid } from "@noya-app/noya-utils";
|
|
957
|
+
import { path } from "imfs";
|
|
958
|
+
var createMediaFolder = (folder) => {
|
|
959
|
+
return {
|
|
960
|
+
id: uuid(),
|
|
961
|
+
kind: "folder",
|
|
962
|
+
...folder
|
|
963
|
+
};
|
|
964
|
+
};
|
|
965
|
+
var createMediaAsset = (asset) => {
|
|
966
|
+
return {
|
|
967
|
+
id: uuid(),
|
|
968
|
+
kind: "asset",
|
|
969
|
+
...asset
|
|
970
|
+
};
|
|
971
|
+
};
|
|
972
|
+
var createMediaFile = (file) => {
|
|
973
|
+
return {
|
|
974
|
+
id: uuid(),
|
|
975
|
+
kind: "file",
|
|
976
|
+
...file
|
|
977
|
+
};
|
|
978
|
+
};
|
|
979
|
+
var createMediaItem = (item) => {
|
|
980
|
+
return {
|
|
981
|
+
...item
|
|
982
|
+
};
|
|
983
|
+
};
|
|
984
|
+
var rootMediaItem = {
|
|
985
|
+
id: "root",
|
|
986
|
+
kind: "folder"
|
|
987
|
+
};
|
|
988
|
+
var rootMediaItemPath = ".";
|
|
989
|
+
var rootMediaItemName = "All Files";
|
|
990
|
+
var PLACEHOLDER_ITEM_NAME = "placeholder";
|
|
991
|
+
var createMediaItemTree = (mediaMap) => {
|
|
992
|
+
const sortedMediaMap = Object.fromEntries(
|
|
993
|
+
Object.entries(mediaMap).sort((a, b) => a[0].localeCompare(b[0]))
|
|
994
|
+
);
|
|
995
|
+
const parentToChildrenMap = /* @__PURE__ */ new Map();
|
|
996
|
+
const idToPathMap = /* @__PURE__ */ new Map();
|
|
997
|
+
idToPathMap.set(rootMediaItem.id, rootMediaItemPath);
|
|
998
|
+
for (const [itemPath, item] of Object.entries(sortedMediaMap)) {
|
|
999
|
+
const parentPath = path.dirname(itemPath);
|
|
1000
|
+
const children = parentToChildrenMap.get(parentPath) ?? [];
|
|
1001
|
+
children.push(item);
|
|
1002
|
+
parentToChildrenMap.set(parentPath, children);
|
|
1003
|
+
idToPathMap.set(item.id, itemPath);
|
|
1004
|
+
}
|
|
1005
|
+
const tree = (0, import_tree_visit.defineTree)({
|
|
1006
|
+
getChildren: (item) => {
|
|
1007
|
+
const itemPath = item === rootMediaItem ? rootMediaItemPath : idToPathMap.get(item.id);
|
|
1008
|
+
if (!itemPath) return [];
|
|
1009
|
+
return parentToChildrenMap.get(itemPath) ?? [];
|
|
1010
|
+
},
|
|
1011
|
+
onDetectCycle: "skip",
|
|
1012
|
+
getIdentifier: (item) => item.id
|
|
1013
|
+
});
|
|
1014
|
+
const result = tree.withOptions({
|
|
1015
|
+
getLabel: (item) => idToPathMap.get(item.id) ?? ""
|
|
1016
|
+
});
|
|
1017
|
+
const mediaItemsWithRoot = [...Object.values(sortedMediaMap), rootMediaItem];
|
|
1018
|
+
const getNameForId = (id) => id === rootMediaItem.id ? rootMediaItemName : path.basename(idToPathMap.get(id) ?? "");
|
|
1019
|
+
const getParentIdForId = (id) => {
|
|
1020
|
+
const itemPath = idToPathMap.get(id);
|
|
1021
|
+
if (!itemPath) return;
|
|
1022
|
+
const parentPath = path.dirname(itemPath);
|
|
1023
|
+
return idToPathMap.get(parentPath);
|
|
1024
|
+
};
|
|
1025
|
+
return {
|
|
1026
|
+
...result,
|
|
1027
|
+
idToPathMap,
|
|
1028
|
+
parentToChildrenMap,
|
|
1029
|
+
mediaItemsWithRoot,
|
|
1030
|
+
getParentIdForId,
|
|
1031
|
+
getNameForId
|
|
1032
|
+
};
|
|
1033
|
+
};
|
|
1034
|
+
|
|
1035
|
+
// src/MediaCollection.tsx
|
|
1036
|
+
import { path as path3 } from "imfs";
|
|
1037
|
+
import React from "react";
|
|
1038
|
+
|
|
1039
|
+
// src/utils/files.ts
|
|
1040
|
+
var import_tree_visit2 = __toESM(require_lib());
|
|
1041
|
+
import { path as path2 } from "imfs";
|
|
1042
|
+
var getVisibleItems = ({
|
|
1043
|
+
expandedMap,
|
|
1044
|
+
fileKindFilter,
|
|
1045
|
+
rootItemId,
|
|
1046
|
+
tree,
|
|
1047
|
+
showAllDescendants,
|
|
1048
|
+
showRootItem
|
|
1049
|
+
}) => {
|
|
1050
|
+
const filteredItems = [];
|
|
1051
|
+
const relativeRootItem = tree.find(rootMediaItem, (item) => item.id === rootItemId) ?? rootMediaItem;
|
|
1052
|
+
tree.visit(relativeRootItem, (item) => {
|
|
1053
|
+
if (relativeRootItem.id === item.id) {
|
|
1054
|
+
if (showRootItem) {
|
|
1055
|
+
filteredItems.push(item);
|
|
1056
|
+
}
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
if (item.kind === "file" && fileKindFilter === "all") {
|
|
1060
|
+
filteredItems.push(item);
|
|
1061
|
+
}
|
|
1062
|
+
if (item.kind === "asset" && (fileKindFilter === "assets" || fileKindFilter === "all")) {
|
|
1063
|
+
filteredItems.push(item);
|
|
1064
|
+
}
|
|
1065
|
+
if (item.kind === "folder" && (fileKindFilter === "directories" || fileKindFilter === "all")) {
|
|
1066
|
+
filteredItems.push(item);
|
|
1067
|
+
}
|
|
1068
|
+
if (!expandedMap[item.id] || !showAllDescendants) return "skip";
|
|
1069
|
+
});
|
|
1070
|
+
return filteredItems;
|
|
1071
|
+
};
|
|
1072
|
+
var basenameValidator = (basename) => {
|
|
1073
|
+
if (!basename || basename.trim() === "") return false;
|
|
1074
|
+
const invalidCharsRegex = /[/\\<>:"|?*]/;
|
|
1075
|
+
return !invalidCharsRegex.test(basename);
|
|
1076
|
+
};
|
|
1077
|
+
var validateMediaItemRename = ({
|
|
1078
|
+
basename,
|
|
1079
|
+
selectedItemPath,
|
|
1080
|
+
media
|
|
1081
|
+
}) => {
|
|
1082
|
+
if (!basenameValidator(basename)) return false;
|
|
1083
|
+
const newItemPath = path2.join(path2.dirname(selectedItemPath), basename);
|
|
1084
|
+
const newPathExists = media[newItemPath];
|
|
1085
|
+
if (newPathExists) return false;
|
|
1086
|
+
return true;
|
|
1087
|
+
};
|
|
1088
|
+
var movePathsIntoTarget = ({
|
|
1089
|
+
media,
|
|
1090
|
+
sourceItemPaths,
|
|
1091
|
+
targetItemPath,
|
|
1092
|
+
tree
|
|
1093
|
+
}) => {
|
|
1094
|
+
const ancestors = (0, import_tree_visit2.ancestorPaths)(
|
|
1095
|
+
sourceItemPaths.map((path4) => path4.split("/"))
|
|
1096
|
+
);
|
|
1097
|
+
const mediaClone = { ...media };
|
|
1098
|
+
for (const ancestor of ancestors) {
|
|
1099
|
+
const ancestorPath = ancestor.join("/");
|
|
1100
|
+
const ancestorItem = mediaClone[ancestorPath];
|
|
1101
|
+
const newAncestorPath = path2.join(
|
|
1102
|
+
targetItemPath,
|
|
1103
|
+
path2.basename(ancestorPath)
|
|
1104
|
+
);
|
|
1105
|
+
if (!ancestorItem) continue;
|
|
1106
|
+
const descendantPaths = tree.flat(ancestorItem).map((item) => tree.idToPathMap.get(item.id));
|
|
1107
|
+
for (const descendantPath of descendantPaths) {
|
|
1108
|
+
if (!descendantPath) continue;
|
|
1109
|
+
const newDescendantPath = descendantPath.replace(
|
|
1110
|
+
ancestorPath,
|
|
1111
|
+
newAncestorPath
|
|
1112
|
+
);
|
|
1113
|
+
const newPathIsValid = validateMediaItemRename({
|
|
1114
|
+
basename: path2.basename(descendantPath),
|
|
1115
|
+
selectedItemPath: newDescendantPath,
|
|
1116
|
+
media
|
|
1117
|
+
});
|
|
1118
|
+
if (newPathIsValid) {
|
|
1119
|
+
mediaClone[newDescendantPath] = mediaClone[descendantPath];
|
|
1120
|
+
delete mediaClone[descendantPath];
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
return mediaClone;
|
|
1125
|
+
};
|
|
1126
|
+
var moveUpAFolder = ({
|
|
1127
|
+
tree,
|
|
1128
|
+
media,
|
|
1129
|
+
selectedIds
|
|
1130
|
+
}) => {
|
|
1131
|
+
const indexPath = tree.findIndexPath(
|
|
1132
|
+
rootMediaItem,
|
|
1133
|
+
(item) => item.id === selectedIds[0]
|
|
1134
|
+
);
|
|
1135
|
+
if (!indexPath) return;
|
|
1136
|
+
const grandparentFolder = tree.access(
|
|
1137
|
+
rootMediaItem,
|
|
1138
|
+
indexPath.slice(0, indexPath.length - 2)
|
|
1139
|
+
);
|
|
1140
|
+
const grandparentFolderPath = tree.idToPathMap.get(grandparentFolder.id);
|
|
1141
|
+
if (!grandparentFolderPath) return;
|
|
1142
|
+
const sourceItemPaths = selectedIds.map((id) => tree.idToPathMap.get(id)).filter((path4) => Boolean(path4));
|
|
1143
|
+
return movePathsIntoTarget({
|
|
1144
|
+
media,
|
|
1145
|
+
targetItemPath: grandparentFolderPath,
|
|
1146
|
+
sourceItemPaths,
|
|
1147
|
+
tree
|
|
1148
|
+
});
|
|
1149
|
+
};
|
|
1150
|
+
var getDepthMap = (item, tree, showAllDescendants) => {
|
|
1151
|
+
const depthMap = {};
|
|
1152
|
+
tree.visit(item, (item2, indexPath) => {
|
|
1153
|
+
if (showAllDescendants) {
|
|
1154
|
+
depthMap[item2.id] = Math.max(indexPath.length - 1, 0);
|
|
1155
|
+
} else {
|
|
1156
|
+
depthMap[item2.id] = 0;
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
return depthMap;
|
|
1160
|
+
};
|
|
1161
|
+
var updateExpandedMap = ({
|
|
1162
|
+
item,
|
|
1163
|
+
expanded,
|
|
1164
|
+
expandable,
|
|
1165
|
+
expandedMap,
|
|
1166
|
+
tree
|
|
1167
|
+
}) => {
|
|
1168
|
+
const newExpandedMap = { ...expandedMap };
|
|
1169
|
+
const inner = (item2, expanded2) => {
|
|
1170
|
+
if (!expandable) return {};
|
|
1171
|
+
if (item2.id === rootMediaItem.id) return {};
|
|
1172
|
+
if (!expanded2) {
|
|
1173
|
+
const children = tree.getChildren(item2, []);
|
|
1174
|
+
children.forEach((child) => inner(child, false));
|
|
1175
|
+
}
|
|
1176
|
+
newExpandedMap[item2.id] = expanded2;
|
|
1177
|
+
};
|
|
1178
|
+
inner(item, expanded);
|
|
1179
|
+
return newExpandedMap;
|
|
1180
|
+
};
|
|
1181
|
+
var deleteMediaItems = ({
|
|
1182
|
+
selectedIds,
|
|
1183
|
+
media,
|
|
1184
|
+
tree
|
|
1185
|
+
}) => {
|
|
1186
|
+
const itemsToDelete = selectedIds.flatMap((mediaItemId) => {
|
|
1187
|
+
const mediaItem = tree.mediaItemsWithRoot.find(
|
|
1188
|
+
(item) => item.id === mediaItemId
|
|
1189
|
+
);
|
|
1190
|
+
if (!mediaItem) return [];
|
|
1191
|
+
return tree.flat(mediaItem);
|
|
1192
|
+
});
|
|
1193
|
+
const itemKeysToDelete = new Set(
|
|
1194
|
+
itemsToDelete.map((item) => tree.idToPathMap.get(item.id))
|
|
1195
|
+
);
|
|
1196
|
+
return Object.fromEntries(
|
|
1197
|
+
Object.entries(media).filter(([key]) => !itemKeysToDelete.has(key))
|
|
1198
|
+
);
|
|
1199
|
+
};
|
|
1200
|
+
var moveMediaInsideFolder = ({
|
|
1201
|
+
sourceItemIds,
|
|
1202
|
+
targetItemId,
|
|
1203
|
+
media,
|
|
1204
|
+
tree
|
|
1205
|
+
}) => {
|
|
1206
|
+
const targetItemPath = tree.idToPathMap.get(targetItemId);
|
|
1207
|
+
if (!targetItemPath) return media;
|
|
1208
|
+
const sourceItemPaths = sourceItemIds.map((id) => tree.idToPathMap.get(id)).filter((path4) => Boolean(path4));
|
|
1209
|
+
return movePathsIntoTarget({
|
|
1210
|
+
media,
|
|
1211
|
+
sourceItemPaths,
|
|
1212
|
+
targetItemPath,
|
|
1213
|
+
tree
|
|
1214
|
+
});
|
|
1215
|
+
};
|
|
1216
|
+
var getParentDirectories = (mediaMap, folderId) => {
|
|
1217
|
+
const tree = createMediaItemTree(mediaMap);
|
|
1218
|
+
const indexPath = tree.findIndexPath(
|
|
1219
|
+
rootMediaItem,
|
|
1220
|
+
(item) => item.id === folderId
|
|
1221
|
+
);
|
|
1222
|
+
if (!indexPath) return [rootMediaItem];
|
|
1223
|
+
return tree.accessPath(rootMediaItem, indexPath);
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1226
|
+
// src/MediaCollection.tsx
|
|
1227
|
+
var MediaThumbnailInternal = memoGeneric(
|
|
1228
|
+
({ item, selected }) => {
|
|
1229
|
+
const asset = useAsset(item.kind === "asset" ? item.assetId : void 0);
|
|
1230
|
+
const isRoot = item.id === rootMediaItem.id;
|
|
1231
|
+
const isFolder = item.kind === "folder";
|
|
1232
|
+
return /* @__PURE__ */ React.createElement(
|
|
1233
|
+
MediaThumbnail,
|
|
1234
|
+
{
|
|
1235
|
+
contentType: asset?.contentType,
|
|
1236
|
+
iconName: isRoot ? "HomeIcon" : isFolder ? "FolderIcon" : void 0,
|
|
1237
|
+
url: asset?.url,
|
|
1238
|
+
selected
|
|
1239
|
+
}
|
|
1240
|
+
);
|
|
1241
|
+
}
|
|
1242
|
+
);
|
|
1243
|
+
var MediaCollection = memo(
|
|
1244
|
+
forwardRef(function MediaCollection2({
|
|
1245
|
+
onSelectionChange,
|
|
1246
|
+
selectedIds: selectedIdsProp,
|
|
1247
|
+
media,
|
|
1248
|
+
setMedia,
|
|
1249
|
+
viewType = "list",
|
|
1250
|
+
fileKindFilter = "all",
|
|
1251
|
+
showRootItem = false,
|
|
1252
|
+
initialExpanded,
|
|
1253
|
+
expandable = true,
|
|
1254
|
+
renamable = true,
|
|
1255
|
+
onDoubleClickItem,
|
|
1256
|
+
rootItemId = rootMediaItem.id,
|
|
1257
|
+
title,
|
|
1258
|
+
size = "medium",
|
|
1259
|
+
right,
|
|
1260
|
+
renderAction: renderActionProp,
|
|
1261
|
+
className,
|
|
1262
|
+
showUploadButton = true,
|
|
1263
|
+
showAllDescendants = true,
|
|
1264
|
+
scrollable = false,
|
|
1265
|
+
sortable = false,
|
|
1266
|
+
renderEmptyState
|
|
1267
|
+
}, ref) {
|
|
1268
|
+
const tree = useMemo(() => createMediaItemTree(media), [media]);
|
|
1269
|
+
const [tempItem, setTempItem] = useState(
|
|
1270
|
+
void 0
|
|
1271
|
+
);
|
|
1272
|
+
const treeWithTempItem = useMemo(
|
|
1273
|
+
() => createMediaItemTree({
|
|
1274
|
+
...media,
|
|
1275
|
+
...tempItem ? { [tempItem[0]]: tempItem[1] } : {}
|
|
1276
|
+
}),
|
|
1277
|
+
[media, tempItem]
|
|
1278
|
+
);
|
|
1279
|
+
const [selectedIds, setSelectedIds] = useControlledOrUncontrolled(
|
|
1280
|
+
{
|
|
1281
|
+
defaultValue: [],
|
|
1282
|
+
value: selectedIdsProp,
|
|
1283
|
+
onChange: onSelectionChange
|
|
1284
|
+
}
|
|
1285
|
+
);
|
|
1286
|
+
const assetManager = useAssetManager();
|
|
1287
|
+
const assets = useAssets();
|
|
1288
|
+
const [expandedMap, setExpandedMap] = useState({});
|
|
1289
|
+
const visibleItems = useMemo(
|
|
1290
|
+
() => getVisibleItems({
|
|
1291
|
+
expandedMap,
|
|
1292
|
+
fileKindFilter,
|
|
1293
|
+
rootItemId,
|
|
1294
|
+
tree: treeWithTempItem,
|
|
1295
|
+
showAllDescendants,
|
|
1296
|
+
showRootItem
|
|
1297
|
+
}),
|
|
1298
|
+
[
|
|
1299
|
+
expandedMap,
|
|
1300
|
+
fileKindFilter,
|
|
1301
|
+
rootItemId,
|
|
1302
|
+
treeWithTempItem,
|
|
1303
|
+
showAllDescendants,
|
|
1304
|
+
showRootItem
|
|
1305
|
+
]
|
|
1306
|
+
);
|
|
1307
|
+
const depthMap = useMemo(
|
|
1308
|
+
() => getDepthMap(rootMediaItem, treeWithTempItem, showAllDescendants),
|
|
1309
|
+
[treeWithTempItem, showAllDescendants]
|
|
1310
|
+
);
|
|
1311
|
+
const collectionRef = useRef(null);
|
|
1312
|
+
const selectedMediaItems = useMemo(
|
|
1313
|
+
() => treeWithTempItem.mediaItemsWithRoot.filter(
|
|
1314
|
+
(item) => selectedIds.includes(item.id)
|
|
1315
|
+
),
|
|
1316
|
+
[treeWithTempItem, selectedIds]
|
|
1317
|
+
);
|
|
1318
|
+
const groupedItems = groupBy(selectedMediaItems, (item) => item.kind);
|
|
1319
|
+
const selectedAssetItems = groupedItems.asset ?? [];
|
|
1320
|
+
const selectedFolderItems = groupedItems.folder ?? [];
|
|
1321
|
+
const singleItemSelected = selectedMediaItems.length === 1;
|
|
1322
|
+
const onlyAssetsSelected = selectedAssetItems.length > 0 && selectedAssetItems.length === selectedMediaItems.length;
|
|
1323
|
+
const onlyFoldersSelected = selectedFolderItems.length > 0 && selectedFolderItems.length === selectedMediaItems.length;
|
|
1324
|
+
const onlySingleFolderSelected = onlyFoldersSelected && selectedFolderItems.length === 1;
|
|
1325
|
+
const onlySingleAssetSelected = onlyAssetsSelected && selectedAssetItems.length === 1;
|
|
1326
|
+
const rootSelected = selectedIds.includes(rootMediaItem.id);
|
|
1327
|
+
const sameParentSelected = selectedMediaItems.every((item) => {
|
|
1328
|
+
const itemPath = tree.idToPathMap.get(item.id);
|
|
1329
|
+
const firstSelectedPath = tree.idToPathMap.get(selectedIds[0]);
|
|
1330
|
+
if (!itemPath || !firstSelectedPath) return false;
|
|
1331
|
+
return itemPath.startsWith(path3.dirname(firstSelectedPath));
|
|
1332
|
+
});
|
|
1333
|
+
const gridSize = useMemo(() => {
|
|
1334
|
+
if (viewType === "grid") {
|
|
1335
|
+
return size;
|
|
1336
|
+
}
|
|
1337
|
+
return "medium";
|
|
1338
|
+
}, [viewType, size]);
|
|
1339
|
+
useEffect(() => {
|
|
1340
|
+
if (initialExpanded) {
|
|
1341
|
+
setExpandedMap(initialExpanded);
|
|
1342
|
+
}
|
|
1343
|
+
}, [initialExpanded]);
|
|
1344
|
+
const handleExpanded = useCallback(
|
|
1345
|
+
(item) => {
|
|
1346
|
+
if (!expandable) return void 0;
|
|
1347
|
+
if (item.kind !== "folder") return void 0;
|
|
1348
|
+
if (item.id === rootMediaItem.id) return void 0;
|
|
1349
|
+
return expandedMap[item.id] ?? false;
|
|
1350
|
+
},
|
|
1351
|
+
[expandedMap, expandable]
|
|
1352
|
+
);
|
|
1353
|
+
const handleDelete = useCallback(
|
|
1354
|
+
(selectedIds2) => {
|
|
1355
|
+
const newMedia = deleteMediaItems({
|
|
1356
|
+
selectedIds: selectedIds2,
|
|
1357
|
+
media,
|
|
1358
|
+
tree
|
|
1359
|
+
});
|
|
1360
|
+
setSelectedIds([rootMediaItem.id]);
|
|
1361
|
+
setMedia({ name: "Delete items", timestamp: Date.now() }, newMedia);
|
|
1362
|
+
},
|
|
1363
|
+
[media, setMedia, setSelectedIds, tree]
|
|
1364
|
+
);
|
|
1365
|
+
const onRename = useCallback(
|
|
1366
|
+
(selectedItem, newName) => {
|
|
1367
|
+
if (!renamable) return;
|
|
1368
|
+
const selectedItemPath = treeWithTempItem.idToPathMap.get(
|
|
1369
|
+
selectedItem.id
|
|
1370
|
+
);
|
|
1371
|
+
if (!selectedItemPath) return;
|
|
1372
|
+
const mediaWithTempItem = {
|
|
1373
|
+
...media,
|
|
1374
|
+
...tempItem ? { [tempItem[0]]: tempItem[1] } : {}
|
|
1375
|
+
};
|
|
1376
|
+
const renameIsValid = validateMediaItemRename({
|
|
1377
|
+
basename: newName,
|
|
1378
|
+
selectedItemPath,
|
|
1379
|
+
media: mediaWithTempItem
|
|
1380
|
+
});
|
|
1381
|
+
if (!renameIsValid) {
|
|
1382
|
+
setTempItem(void 0);
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
const mediaClone = { ...media };
|
|
1386
|
+
delete mediaClone[selectedItemPath];
|
|
1387
|
+
setMedia(
|
|
1388
|
+
{ name: "Rename media item", timestamp: Date.now() },
|
|
1389
|
+
{
|
|
1390
|
+
...mediaClone,
|
|
1391
|
+
[path3.join(path3.dirname(selectedItemPath), newName)]: selectedItem
|
|
1392
|
+
}
|
|
1393
|
+
);
|
|
1394
|
+
setTempItem(void 0);
|
|
1395
|
+
},
|
|
1396
|
+
[media, renamable, setMedia, tempItem, treeWithTempItem.idToPathMap]
|
|
1397
|
+
);
|
|
1398
|
+
const handleAddFolder = useCallback(
|
|
1399
|
+
(currentFolderId) => {
|
|
1400
|
+
const newFolder = createMediaFolder();
|
|
1401
|
+
const currentFolderPath = tree.idToPathMap.get(currentFolderId);
|
|
1402
|
+
if (!currentFolderPath) return;
|
|
1403
|
+
setTempItem([
|
|
1404
|
+
path3.join(currentFolderPath, PLACEHOLDER_ITEM_NAME),
|
|
1405
|
+
newFolder
|
|
1406
|
+
]);
|
|
1407
|
+
setTimeout(() => {
|
|
1408
|
+
collectionRef.current?.editName(newFolder.id);
|
|
1409
|
+
}, 50);
|
|
1410
|
+
},
|
|
1411
|
+
[tree]
|
|
1412
|
+
);
|
|
1413
|
+
const handleAddFile = useCallback(
|
|
1414
|
+
(currentFolderId) => {
|
|
1415
|
+
const newFile = createMediaFile({
|
|
1416
|
+
content: "",
|
|
1417
|
+
encoding: "utf-8"
|
|
1418
|
+
});
|
|
1419
|
+
const currentFolderPath = tree.idToPathMap.get(
|
|
1420
|
+
currentFolderId ?? rootMediaItem.id
|
|
1421
|
+
);
|
|
1422
|
+
if (!currentFolderPath) return;
|
|
1423
|
+
setTempItem([
|
|
1424
|
+
path3.join(currentFolderPath, PLACEHOLDER_ITEM_NAME),
|
|
1425
|
+
newFile
|
|
1426
|
+
]);
|
|
1427
|
+
setTimeout(() => {
|
|
1428
|
+
collectionRef.current?.editName(newFile.id);
|
|
1429
|
+
}, 50);
|
|
1430
|
+
},
|
|
1431
|
+
[tree.idToPathMap]
|
|
1432
|
+
);
|
|
1433
|
+
const handleMoveUpAFolder = useCallback(
|
|
1434
|
+
(selectedIds2) => {
|
|
1435
|
+
const newMedia = moveUpAFolder({
|
|
1436
|
+
tree,
|
|
1437
|
+
media,
|
|
1438
|
+
selectedIds: selectedIds2
|
|
1439
|
+
});
|
|
1440
|
+
if (!newMedia) return;
|
|
1441
|
+
setMedia({ name: "Move items", timestamp: Date.now() }, newMedia);
|
|
1442
|
+
},
|
|
1443
|
+
[media, tree, setMedia]
|
|
1444
|
+
);
|
|
1445
|
+
const handleUpload = useCallback(
|
|
1446
|
+
async (selectedId) => {
|
|
1447
|
+
try {
|
|
1448
|
+
const files = await fileOpen({ multiple: true });
|
|
1449
|
+
if (!files || !Array.isArray(files) || files.length === 0) return;
|
|
1450
|
+
const parentPath = tree.idToPathMap.get(selectedId);
|
|
1451
|
+
if (!parentPath) return;
|
|
1452
|
+
const uploadPromises = files.map(async (file) => {
|
|
1453
|
+
const asset = await assetManager.create(file);
|
|
1454
|
+
const assetPath = path3.join(parentPath, path3.basename(file.name));
|
|
1455
|
+
return {
|
|
1456
|
+
assetPath,
|
|
1457
|
+
asset: createMediaAsset({ assetId: asset.id })
|
|
1458
|
+
};
|
|
1459
|
+
});
|
|
1460
|
+
const newMediaMap = await Promise.all(uploadPromises);
|
|
1461
|
+
setMedia(
|
|
1462
|
+
{ name: "Add media items", timestamp: Date.now() },
|
|
1463
|
+
{
|
|
1464
|
+
...media,
|
|
1465
|
+
...Object.fromEntries(
|
|
1466
|
+
newMediaMap.map(({ assetPath, asset }) => [assetPath, asset])
|
|
1467
|
+
)
|
|
1468
|
+
}
|
|
1469
|
+
);
|
|
1470
|
+
} catch (error) {
|
|
1471
|
+
console.error("Failed to upload files:", error);
|
|
1472
|
+
}
|
|
1473
|
+
},
|
|
1474
|
+
[tree.idToPathMap, setMedia, media, assetManager]
|
|
1475
|
+
);
|
|
1476
|
+
const handleDownload = useCallback(
|
|
1477
|
+
async (selectedItems) => {
|
|
1478
|
+
const downloadPromises = selectedItems.filter((item) => item.kind === "asset").map(async (item) => {
|
|
1479
|
+
const asset = assets.find((a) => a.id === item.assetId);
|
|
1480
|
+
if (!asset?.url) return;
|
|
1481
|
+
return downloadUrl(asset.url, tree.getNameForId(item.id));
|
|
1482
|
+
});
|
|
1483
|
+
await Promise.all(downloadPromises);
|
|
1484
|
+
},
|
|
1485
|
+
[assets, tree]
|
|
1486
|
+
);
|
|
1487
|
+
const handlePreview = useCallback(
|
|
1488
|
+
async (selectedItems) => {
|
|
1489
|
+
const previewPromises = selectedItems.filter((item) => item.kind === "asset").map(async (item) => {
|
|
1490
|
+
const asset = assets.find((a) => a.id === item.assetId);
|
|
1491
|
+
if (!asset?.url) return;
|
|
1492
|
+
return window?.open(asset.url, "_blank");
|
|
1493
|
+
});
|
|
1494
|
+
await Promise.all(previewPromises);
|
|
1495
|
+
},
|
|
1496
|
+
[assets]
|
|
1497
|
+
);
|
|
1498
|
+
const handleReplace = useCallback(
|
|
1499
|
+
async (selectedItem) => {
|
|
1500
|
+
try {
|
|
1501
|
+
const file = await fileOpen();
|
|
1502
|
+
if (!file) return;
|
|
1503
|
+
const asset = await assetManager.create(file);
|
|
1504
|
+
const oldFile = selectedItem;
|
|
1505
|
+
const oldFilePath = tree.idToPathMap.get(oldFile.id);
|
|
1506
|
+
if (!oldFilePath || oldFile.kind !== "asset") return;
|
|
1507
|
+
setMedia(
|
|
1508
|
+
{ name: "Replace media file", timestamp: Date.now() },
|
|
1509
|
+
{
|
|
1510
|
+
...media,
|
|
1511
|
+
[oldFilePath]: createMediaAsset({
|
|
1512
|
+
...oldFile,
|
|
1513
|
+
assetId: asset.id
|
|
1514
|
+
})
|
|
1515
|
+
}
|
|
1516
|
+
);
|
|
1517
|
+
} catch (error) {
|
|
1518
|
+
console.error("Failed to upload file:", error);
|
|
1519
|
+
}
|
|
1520
|
+
},
|
|
1521
|
+
[media, setMedia, assetManager, tree]
|
|
1522
|
+
);
|
|
1523
|
+
const handleRename = useCallback(
|
|
1524
|
+
(selectedItemId) => {
|
|
1525
|
+
collectionRef.current?.editName(selectedItemId);
|
|
1526
|
+
},
|
|
1527
|
+
[collectionRef]
|
|
1528
|
+
);
|
|
1529
|
+
const handleMoveMediaInsideFolder = useCallback(
|
|
1530
|
+
(sourceItem, targetItem) => {
|
|
1531
|
+
const sourceItemPath = tree.idToPathMap.get(sourceItem.id);
|
|
1532
|
+
const targetItemPath = tree.idToPathMap.get(targetItem.id);
|
|
1533
|
+
if (!sourceItemPath || !targetItemPath) return;
|
|
1534
|
+
const newMedia = moveMediaInsideFolder({
|
|
1535
|
+
sourceItemIds: [sourceItem.id],
|
|
1536
|
+
targetItemId: targetItem.id,
|
|
1537
|
+
media,
|
|
1538
|
+
tree
|
|
1539
|
+
});
|
|
1540
|
+
setMedia(
|
|
1541
|
+
{
|
|
1542
|
+
name: "Move media file inside folder",
|
|
1543
|
+
timestamp: Date.now()
|
|
1544
|
+
},
|
|
1545
|
+
newMedia
|
|
1546
|
+
);
|
|
1547
|
+
},
|
|
1548
|
+
[media, setMedia, tree]
|
|
1549
|
+
);
|
|
1550
|
+
const assetContextMenuItems = useMemo(() => {
|
|
1551
|
+
return createSectionedMenu(
|
|
1552
|
+
[
|
|
1553
|
+
!rootSelected && singleItemSelected && {
|
|
1554
|
+
title: "Rename",
|
|
1555
|
+
value: "rename",
|
|
1556
|
+
icon: /* @__PURE__ */ React.createElement(InputIcon, null)
|
|
1557
|
+
},
|
|
1558
|
+
onlySingleAssetSelected && {
|
|
1559
|
+
title: "Replace",
|
|
1560
|
+
value: "replace",
|
|
1561
|
+
icon: /* @__PURE__ */ React.createElement(UpdateIcon, null)
|
|
1562
|
+
},
|
|
1563
|
+
!rootSelected && {
|
|
1564
|
+
title: "Delete",
|
|
1565
|
+
value: "delete",
|
|
1566
|
+
icon: /* @__PURE__ */ React.createElement(TrashIcon, null)
|
|
1567
|
+
}
|
|
1568
|
+
],
|
|
1569
|
+
[
|
|
1570
|
+
onlySingleFolderSelected && {
|
|
1571
|
+
title: "Add media",
|
|
1572
|
+
value: "upload",
|
|
1573
|
+
icon: /* @__PURE__ */ React.createElement(UploadIcon, null)
|
|
1574
|
+
},
|
|
1575
|
+
onlySingleFolderSelected && {
|
|
1576
|
+
title: "Add a Folder",
|
|
1577
|
+
value: "addFolder",
|
|
1578
|
+
icon: /* @__PURE__ */ React.createElement(FolderIcon, null)
|
|
1579
|
+
},
|
|
1580
|
+
onlyAssetsSelected && tree.mediaItemsWithRoot.length > 0 && {
|
|
1581
|
+
title: "Download",
|
|
1582
|
+
value: "download",
|
|
1583
|
+
icon: /* @__PURE__ */ React.createElement(DownloadIcon, null)
|
|
1584
|
+
},
|
|
1585
|
+
onlySingleAssetSelected && {
|
|
1586
|
+
title: "Preview",
|
|
1587
|
+
value: "preview",
|
|
1588
|
+
icon: /* @__PURE__ */ React.createElement(OpenInNewWindowIcon, null)
|
|
1589
|
+
}
|
|
1590
|
+
],
|
|
1591
|
+
[
|
|
1592
|
+
!rootSelected && sameParentSelected && {
|
|
1593
|
+
title: "Move up a folder",
|
|
1594
|
+
value: "move",
|
|
1595
|
+
icon: /* @__PURE__ */ React.createElement(ResetIcon, null)
|
|
1596
|
+
}
|
|
1597
|
+
]
|
|
1598
|
+
);
|
|
1599
|
+
}, [
|
|
1600
|
+
rootSelected,
|
|
1601
|
+
singleItemSelected,
|
|
1602
|
+
onlySingleAssetSelected,
|
|
1603
|
+
onlySingleFolderSelected,
|
|
1604
|
+
onlyAssetsSelected,
|
|
1605
|
+
tree.mediaItemsWithRoot.length,
|
|
1606
|
+
sameParentSelected
|
|
1607
|
+
]);
|
|
1608
|
+
const handleMenuAction = useCallback(
|
|
1609
|
+
async (action, selectedItems) => {
|
|
1610
|
+
if (selectedItems.length === 0) return;
|
|
1611
|
+
switch (action) {
|
|
1612
|
+
case "rename":
|
|
1613
|
+
handleRename(selectedItems[0].id);
|
|
1614
|
+
return;
|
|
1615
|
+
case "delete":
|
|
1616
|
+
handleDelete(selectedIds);
|
|
1617
|
+
return;
|
|
1618
|
+
case "replace":
|
|
1619
|
+
handleReplace(selectedItems[0]);
|
|
1620
|
+
return;
|
|
1621
|
+
case "upload":
|
|
1622
|
+
handleUpload(selectedItems[0].id);
|
|
1623
|
+
return;
|
|
1624
|
+
case "addFolder":
|
|
1625
|
+
handleAddFolder(selectedItems[0].id);
|
|
1626
|
+
return;
|
|
1627
|
+
case "preview":
|
|
1628
|
+
handlePreview(selectedItems);
|
|
1629
|
+
return;
|
|
1630
|
+
case "download":
|
|
1631
|
+
handleDownload(selectedItems);
|
|
1632
|
+
return;
|
|
1633
|
+
case "move":
|
|
1634
|
+
handleMoveUpAFolder(selectedIds);
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
},
|
|
1638
|
+
[
|
|
1639
|
+
handleRename,
|
|
1640
|
+
handleDelete,
|
|
1641
|
+
selectedIds,
|
|
1642
|
+
handleReplace,
|
|
1643
|
+
handleUpload,
|
|
1644
|
+
handleAddFolder,
|
|
1645
|
+
handlePreview,
|
|
1646
|
+
handleDownload,
|
|
1647
|
+
handleMoveUpAFolder
|
|
1648
|
+
]
|
|
1649
|
+
);
|
|
1650
|
+
const handleSetExpanded = useCallback(
|
|
1651
|
+
(item, expanded) => {
|
|
1652
|
+
setExpandedMap(
|
|
1653
|
+
(prev) => updateExpandedMap({
|
|
1654
|
+
item,
|
|
1655
|
+
expanded,
|
|
1656
|
+
expandable,
|
|
1657
|
+
expandedMap: prev,
|
|
1658
|
+
tree
|
|
1659
|
+
})
|
|
1660
|
+
);
|
|
1661
|
+
},
|
|
1662
|
+
[expandable, tree]
|
|
1663
|
+
);
|
|
1664
|
+
const renderAction = useMemo(() => {
|
|
1665
|
+
if (renderActionProp) return renderActionProp;
|
|
1666
|
+
return ({
|
|
1667
|
+
selected,
|
|
1668
|
+
onOpenChange
|
|
1669
|
+
}) => /* @__PURE__ */ React.createElement(
|
|
1670
|
+
ActionMenu,
|
|
1671
|
+
{
|
|
1672
|
+
menuItems: assetContextMenuItems,
|
|
1673
|
+
onSelect: (action) => handleMenuAction(action, selectedMediaItems),
|
|
1674
|
+
selected,
|
|
1675
|
+
onOpenChange,
|
|
1676
|
+
style: {
|
|
1677
|
+
backgroundColor: selected ? cssVars.colors.primaryPastel : "transparent"
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
);
|
|
1681
|
+
}, [
|
|
1682
|
+
assetContextMenuItems,
|
|
1683
|
+
handleMenuAction,
|
|
1684
|
+
renderActionProp,
|
|
1685
|
+
selectedMediaItems
|
|
1686
|
+
]);
|
|
1687
|
+
useImperativeHandle(ref, () => ({
|
|
1688
|
+
upload: (selectedId) => handleUpload(selectedId),
|
|
1689
|
+
delete: handleDelete,
|
|
1690
|
+
download: handleDownload,
|
|
1691
|
+
rename: handleRename,
|
|
1692
|
+
addFolder: handleAddFolder,
|
|
1693
|
+
addFile: handleAddFile,
|
|
1694
|
+
moveUpAFolder: handleMoveUpAFolder,
|
|
1695
|
+
replace: handleReplace,
|
|
1696
|
+
preview: handlePreview,
|
|
1697
|
+
moveMediaInsideFolder: handleMoveMediaInsideFolder
|
|
1698
|
+
}));
|
|
1699
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1700
|
+
FileExplorerLayout,
|
|
1701
|
+
{
|
|
1702
|
+
title: title ?? rootMediaItemName,
|
|
1703
|
+
right: /* @__PURE__ */ React.createElement(
|
|
1704
|
+
FileExplorerUploadButton,
|
|
1705
|
+
{
|
|
1706
|
+
showUploadButton,
|
|
1707
|
+
onUpload: () => handleUpload(rootMediaItem.id)
|
|
1708
|
+
},
|
|
1709
|
+
right
|
|
1710
|
+
),
|
|
1711
|
+
className
|
|
1712
|
+
},
|
|
1713
|
+
/* @__PURE__ */ React.createElement(
|
|
1714
|
+
FileExplorerCollection,
|
|
1715
|
+
{
|
|
1716
|
+
ref: collectionRef,
|
|
1717
|
+
scrollable,
|
|
1718
|
+
items: visibleItems,
|
|
1719
|
+
viewType,
|
|
1720
|
+
size: gridSize,
|
|
1721
|
+
getId: (file) => file.id,
|
|
1722
|
+
getName: (file) => {
|
|
1723
|
+
if (file.id === tempItem?.[1].id) {
|
|
1724
|
+
return "";
|
|
1725
|
+
}
|
|
1726
|
+
return treeWithTempItem.getNameForId(file.id);
|
|
1727
|
+
},
|
|
1728
|
+
expandable,
|
|
1729
|
+
sortable,
|
|
1730
|
+
getPlaceholder: (item) => {
|
|
1731
|
+
switch (item.kind) {
|
|
1732
|
+
case "folder":
|
|
1733
|
+
return "Enter folder name";
|
|
1734
|
+
case "asset":
|
|
1735
|
+
case "file":
|
|
1736
|
+
return "Enter file name";
|
|
1737
|
+
}
|
|
1738
|
+
},
|
|
1739
|
+
getExpanded: handleExpanded,
|
|
1740
|
+
setExpanded: handleSetExpanded,
|
|
1741
|
+
getRenamable: (item) => {
|
|
1742
|
+
if (item.id === rootMediaItem.id) return false;
|
|
1743
|
+
return true;
|
|
1744
|
+
},
|
|
1745
|
+
getDepth: (item) => depthMap[item.id],
|
|
1746
|
+
menuItems: assetContextMenuItems,
|
|
1747
|
+
onSelectMenuItem: handleMenuAction,
|
|
1748
|
+
onSelectionChange: setSelectedIds,
|
|
1749
|
+
onDoubleClickItem,
|
|
1750
|
+
onRename,
|
|
1751
|
+
renamable,
|
|
1752
|
+
selectedIds,
|
|
1753
|
+
renderThumbnail: (props) => /* @__PURE__ */ React.createElement(MediaThumbnailInternal, { ...props }),
|
|
1754
|
+
renderAction,
|
|
1755
|
+
renderDetail: (file, selected) => {
|
|
1756
|
+
if (file.kind !== "asset") return null;
|
|
1757
|
+
const asset = assets.find((a) => a.id === file.assetId);
|
|
1758
|
+
if (!asset) return null;
|
|
1759
|
+
return /* @__PURE__ */ React.createElement(FileExplorerDetail, { selected }, (asset.size / 1024).toFixed(1), "KB");
|
|
1760
|
+
},
|
|
1761
|
+
renderEmptyState: () => renderEmptyState?.() ?? /* @__PURE__ */ React.createElement(FileExplorerEmptyState, null),
|
|
1762
|
+
itemRoleDescription: "clickable file item",
|
|
1763
|
+
getDropTargetParentIndex: (overIndex) => {
|
|
1764
|
+
const item = visibleItems[overIndex];
|
|
1765
|
+
const parentIndex = visibleItems.findIndex(
|
|
1766
|
+
(i) => i.id === tree.getParentIdForId(item.id)
|
|
1767
|
+
);
|
|
1768
|
+
return parentIndex === -1 ? void 0 : parentIndex;
|
|
1769
|
+
},
|
|
1770
|
+
acceptsDrop: (sourceIndex, targetIndex, position) => {
|
|
1771
|
+
const sourceItem = visibleItems[sourceIndex];
|
|
1772
|
+
const targetItem = visibleItems[targetIndex];
|
|
1773
|
+
if (position !== "inside" || targetItem.kind === "asset") {
|
|
1774
|
+
return false;
|
|
1775
|
+
}
|
|
1776
|
+
const sourcePath = tree.findIndexPath(
|
|
1777
|
+
rootMediaItem,
|
|
1778
|
+
(item) => item.id === sourceItem.id
|
|
1779
|
+
);
|
|
1780
|
+
const targetPath = tree.findIndexPath(
|
|
1781
|
+
rootMediaItem,
|
|
1782
|
+
(item) => item.id === targetItem.id
|
|
1783
|
+
);
|
|
1784
|
+
if (!sourcePath || !targetPath) return false;
|
|
1785
|
+
if (isDeepEqual(sourcePath, targetPath.slice(0, sourcePath.length))) {
|
|
1786
|
+
return false;
|
|
1787
|
+
}
|
|
1788
|
+
return true;
|
|
1789
|
+
},
|
|
1790
|
+
onMoveItem: (sourceIndex, targetIndex, position) => {
|
|
1791
|
+
const sourceItem = visibleItems[sourceIndex];
|
|
1792
|
+
const targetItem = visibleItems[targetIndex];
|
|
1793
|
+
if (position === "inside") {
|
|
1794
|
+
handleMoveMediaInsideFolder(sourceItem, targetItem);
|
|
1795
|
+
}
|
|
1796
|
+
},
|
|
1797
|
+
onFilesDrop: async (event) => {
|
|
1798
|
+
event.preventDefault();
|
|
1799
|
+
const files = Array.from(event.dataTransfer.files);
|
|
1800
|
+
if (files.length === 0) return;
|
|
1801
|
+
try {
|
|
1802
|
+
const uploadPromises = files.map(async (file) => {
|
|
1803
|
+
const asset = await assetManager.create(file);
|
|
1804
|
+
return {
|
|
1805
|
+
asset: createMediaAsset({
|
|
1806
|
+
assetId: asset.id
|
|
1807
|
+
}),
|
|
1808
|
+
name: file.name
|
|
1809
|
+
};
|
|
1810
|
+
});
|
|
1811
|
+
const newMediaItems = await Promise.all(uploadPromises);
|
|
1812
|
+
const rootItemPath = tree.idToPathMap.get(rootItemId);
|
|
1813
|
+
if (!rootItemPath) return;
|
|
1814
|
+
setMedia(
|
|
1815
|
+
{ name: "Add media files", timestamp: Date.now() },
|
|
1816
|
+
{
|
|
1817
|
+
...media,
|
|
1818
|
+
...Object.fromEntries(
|
|
1819
|
+
newMediaItems.map((item) => [
|
|
1820
|
+
path3.join(rootItemPath, item.name),
|
|
1821
|
+
item.asset
|
|
1822
|
+
])
|
|
1823
|
+
)
|
|
1824
|
+
}
|
|
1825
|
+
);
|
|
1826
|
+
} catch (error) {
|
|
1827
|
+
console.error("Failed to upload dropped files:", error);
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
)
|
|
1832
|
+
));
|
|
1833
|
+
})
|
|
1834
|
+
);
|
|
1835
|
+
export {
|
|
1836
|
+
MediaCollection,
|
|
1837
|
+
PLACEHOLDER_ITEM_NAME,
|
|
1838
|
+
basenameValidator,
|
|
1839
|
+
createMediaAsset,
|
|
1840
|
+
createMediaFile,
|
|
1841
|
+
createMediaFolder,
|
|
1842
|
+
createMediaItem,
|
|
1843
|
+
createMediaItemTree,
|
|
1844
|
+
deleteMediaItems,
|
|
1845
|
+
getDepthMap,
|
|
1846
|
+
getParentDirectories,
|
|
1847
|
+
getVisibleItems,
|
|
1848
|
+
moveMediaInsideFolder,
|
|
1849
|
+
movePathsIntoTarget,
|
|
1850
|
+
moveUpAFolder,
|
|
1851
|
+
rootMediaItem,
|
|
1852
|
+
rootMediaItemName,
|
|
1853
|
+
rootMediaItemPath,
|
|
1854
|
+
updateExpandedMap,
|
|
1855
|
+
validateMediaItemRename
|
|
1856
|
+
};
|
|
1857
|
+
//# sourceMappingURL=index.mjs.map
|