@noya-app/noya-file-explorer 0.0.31 → 0.0.32
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/.turbo/turbo-build.log +11 -11
- package/CHANGELOG.md +12 -0
- package/dist/index.css +84 -11
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +731 -211
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +759 -212
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/src/GitFileExplorer.tsx +432 -0
- package/src/git/gitFileTree.ts +110 -0
- package/src/git/useGitFileOperations.ts +184 -0
- package/src/git/useGitFileTree.ts +91 -0
- package/src/index.ts +1 -0
- package/src/utils/handleFileDrop.ts +2 -84
package/dist/index.js
CHANGED
|
@@ -1109,6 +1109,7 @@ var require_lib = __commonJS({
|
|
|
1109
1109
|
// src/index.ts
|
|
1110
1110
|
var src_exports = {};
|
|
1111
1111
|
__export(src_exports, {
|
|
1112
|
+
GitFileExplorer: () => GitFileExplorer2,
|
|
1112
1113
|
MediaCollection: () => MediaCollection,
|
|
1113
1114
|
PLACEHOLDER_ITEM_NAME: () => PLACEHOLDER_ITEM_NAME,
|
|
1114
1115
|
ResourceExplorer: () => ResourceExplorer,
|
|
@@ -1126,7 +1127,7 @@ __export(src_exports, {
|
|
|
1126
1127
|
getContentTypeFromFile: () => getContentTypeFromFile,
|
|
1127
1128
|
getDepthMap: () => getDepthMap,
|
|
1128
1129
|
getParentDirectories: () => getParentDirectories,
|
|
1129
|
-
getVisibleItems: () =>
|
|
1130
|
+
getVisibleItems: () => getVisibleItems2,
|
|
1130
1131
|
gridThumbnailDimension: () => gridThumbnailDimension,
|
|
1131
1132
|
mediaDeleteMediaItems: () => mediaDeleteMediaItems,
|
|
1132
1133
|
mediaGetDepthMap: () => mediaGetDepthMap,
|
|
@@ -1150,14 +1151,596 @@ __export(src_exports, {
|
|
|
1150
1151
|
});
|
|
1151
1152
|
module.exports = __toCommonJS(src_exports);
|
|
1152
1153
|
|
|
1153
|
-
// src/
|
|
1154
|
+
// src/GitFileExplorer.tsx
|
|
1154
1155
|
var import_noya_designsystem = require("@noya-app/noya-designsystem");
|
|
1155
1156
|
var import_noya_icons = require("@noya-app/noya-icons");
|
|
1156
|
-
var
|
|
1157
|
-
var
|
|
1157
|
+
var import_react_utils2 = require("@noya-app/react-utils");
|
|
1158
|
+
var import_react3 = __toESM(require("react"));
|
|
1159
|
+
|
|
1160
|
+
// src/git/gitFileTree.ts
|
|
1161
|
+
function parseFilesToTree(files) {
|
|
1162
|
+
const items = [];
|
|
1163
|
+
const seenDirs = /* @__PURE__ */ new Set();
|
|
1164
|
+
const sortedFiles = [...files].sort();
|
|
1165
|
+
for (const filePath of sortedFiles) {
|
|
1166
|
+
const parts = filePath.split("/");
|
|
1167
|
+
let currentPath = "";
|
|
1168
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
1169
|
+
currentPath = currentPath ? `${currentPath}/${parts[i]}` : parts[i];
|
|
1170
|
+
if (!seenDirs.has(currentPath)) {
|
|
1171
|
+
seenDirs.add(currentPath);
|
|
1172
|
+
items.push({
|
|
1173
|
+
id: `dir:${currentPath}`,
|
|
1174
|
+
name: parts[i],
|
|
1175
|
+
path: currentPath,
|
|
1176
|
+
isDirectory: true,
|
|
1177
|
+
depth: i
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
items.push({
|
|
1182
|
+
id: `file:${filePath}`,
|
|
1183
|
+
name: parts[parts.length - 1],
|
|
1184
|
+
path: filePath,
|
|
1185
|
+
isDirectory: false,
|
|
1186
|
+
depth: parts.length - 1
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
return items;
|
|
1190
|
+
}
|
|
1191
|
+
function getVisibleItems(items, expandedDirs) {
|
|
1192
|
+
const visible = [];
|
|
1193
|
+
const collapsedPrefixes = [];
|
|
1194
|
+
for (const item of items) {
|
|
1195
|
+
const isHidden = collapsedPrefixes.some(
|
|
1196
|
+
(prefix) => item.path.startsWith(prefix + "/")
|
|
1197
|
+
);
|
|
1198
|
+
if (isHidden) continue;
|
|
1199
|
+
visible.push(item);
|
|
1200
|
+
if (item.isDirectory && !expandedDirs.has(item.path)) {
|
|
1201
|
+
collapsedPrefixes.push(item.path);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
return visible;
|
|
1205
|
+
}
|
|
1206
|
+
function createTempFileItem(name = "") {
|
|
1207
|
+
return {
|
|
1208
|
+
id: "temp:new-file",
|
|
1209
|
+
name,
|
|
1210
|
+
path: name,
|
|
1211
|
+
isDirectory: false,
|
|
1212
|
+
depth: 0
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
function isTempItem(item) {
|
|
1216
|
+
return item.id === "temp:new-file";
|
|
1217
|
+
}
|
|
1218
|
+
function computeRenamedPath(oldPath, newName) {
|
|
1219
|
+
const pathParts = oldPath.split("/");
|
|
1220
|
+
pathParts[pathParts.length - 1] = newName;
|
|
1221
|
+
return pathParts.join("/");
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// src/git/useGitFileOperations.ts
|
|
1158
1225
|
var import_react_utils = require("@noya-app/react-utils");
|
|
1159
1226
|
var import_browser_fs_access = require("browser-fs-access");
|
|
1160
1227
|
var import_react = require("react");
|
|
1228
|
+
function useGitFileOperations({
|
|
1229
|
+
repoId,
|
|
1230
|
+
repoFilesState,
|
|
1231
|
+
gitManager
|
|
1232
|
+
}) {
|
|
1233
|
+
const [isUploading, setIsUploading] = (0, import_react.useState)(false);
|
|
1234
|
+
const createFile = (0, import_react.useCallback)(
|
|
1235
|
+
async (path7, content = "") => {
|
|
1236
|
+
try {
|
|
1237
|
+
await gitManager.patchFiles(
|
|
1238
|
+
repoId,
|
|
1239
|
+
{ create: [{ path: path7, content }] },
|
|
1240
|
+
repoFilesState.ref
|
|
1241
|
+
);
|
|
1242
|
+
} catch (error) {
|
|
1243
|
+
alert(`Failed to create file: ${error}`);
|
|
1244
|
+
throw error;
|
|
1245
|
+
}
|
|
1246
|
+
},
|
|
1247
|
+
[gitManager, repoId, repoFilesState.ref]
|
|
1248
|
+
);
|
|
1249
|
+
const renameFile = (0, import_react.useCallback)(
|
|
1250
|
+
async (item, newName) => {
|
|
1251
|
+
if (isTempItem(item)) {
|
|
1252
|
+
if (!newName) return;
|
|
1253
|
+
await createFile(newName);
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
if (item.isDirectory) {
|
|
1257
|
+
alert("Renaming directories is not yet supported");
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
if (newName === item.name) return;
|
|
1261
|
+
const newPath = computeRenamedPath(item.path, newName);
|
|
1262
|
+
try {
|
|
1263
|
+
await gitManager.patchFiles(
|
|
1264
|
+
repoId,
|
|
1265
|
+
{ rename: [{ oldPath: item.path, newPath }] },
|
|
1266
|
+
repoFilesState.ref
|
|
1267
|
+
);
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
alert(`Failed to rename file: ${error}`);
|
|
1270
|
+
throw error;
|
|
1271
|
+
}
|
|
1272
|
+
},
|
|
1273
|
+
[gitManager, repoId, repoFilesState.ref, createFile]
|
|
1274
|
+
);
|
|
1275
|
+
const deleteFiles = (0, import_react.useCallback)(
|
|
1276
|
+
async (items) => {
|
|
1277
|
+
const pathsToDelete = /* @__PURE__ */ new Set();
|
|
1278
|
+
for (const item of items) {
|
|
1279
|
+
if (item.isDirectory) {
|
|
1280
|
+
const dirPrefix = item.path + "/";
|
|
1281
|
+
for (const filePath of repoFilesState.files) {
|
|
1282
|
+
if (filePath.startsWith(dirPrefix)) {
|
|
1283
|
+
pathsToDelete.add(filePath);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
} else {
|
|
1287
|
+
pathsToDelete.add(item.path);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
if (pathsToDelete.size === 0) {
|
|
1291
|
+
return;
|
|
1292
|
+
}
|
|
1293
|
+
try {
|
|
1294
|
+
await gitManager.patchFiles(
|
|
1295
|
+
repoId,
|
|
1296
|
+
{ delete: Array.from(pathsToDelete).map((path7) => ({ path: path7 })) },
|
|
1297
|
+
repoFilesState.ref
|
|
1298
|
+
);
|
|
1299
|
+
} catch (error) {
|
|
1300
|
+
alert(`Failed to delete files: ${error}`);
|
|
1301
|
+
throw error;
|
|
1302
|
+
}
|
|
1303
|
+
},
|
|
1304
|
+
[gitManager, repoId, repoFilesState.ref, repoFilesState.files]
|
|
1305
|
+
);
|
|
1306
|
+
const uploadFiles = (0, import_react.useCallback)(async () => {
|
|
1307
|
+
try {
|
|
1308
|
+
const files = await (0, import_browser_fs_access.fileOpen)({ multiple: true });
|
|
1309
|
+
if (!files || Array.isArray(files) && files.length === 0) return;
|
|
1310
|
+
const fileArray = Array.isArray(files) ? files : [files];
|
|
1311
|
+
setIsUploading(true);
|
|
1312
|
+
const createOperations = await Promise.all(
|
|
1313
|
+
fileArray.map(async (file) => ({
|
|
1314
|
+
path: file.name,
|
|
1315
|
+
content: await (0, import_react_utils.readFileAsText)(file)
|
|
1316
|
+
}))
|
|
1317
|
+
);
|
|
1318
|
+
await gitManager.patchFiles(
|
|
1319
|
+
repoId,
|
|
1320
|
+
{ create: createOperations },
|
|
1321
|
+
repoFilesState.ref
|
|
1322
|
+
);
|
|
1323
|
+
} catch (error) {
|
|
1324
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1325
|
+
} else {
|
|
1326
|
+
alert(`Failed to upload files: ${error}`);
|
|
1327
|
+
}
|
|
1328
|
+
} finally {
|
|
1329
|
+
setIsUploading(false);
|
|
1330
|
+
}
|
|
1331
|
+
}, [gitManager, repoId, repoFilesState.ref]);
|
|
1332
|
+
const handleFileDrop = (0, import_react.useCallback)(
|
|
1333
|
+
async (event) => {
|
|
1334
|
+
event.preventDefault();
|
|
1335
|
+
try {
|
|
1336
|
+
setIsUploading(true);
|
|
1337
|
+
const droppedFiles = await (0, import_react_utils.collectDroppedFiles)(event.dataTransfer);
|
|
1338
|
+
if (droppedFiles.length === 0) return;
|
|
1339
|
+
const createOperations = await Promise.all(
|
|
1340
|
+
droppedFiles.map(async ({ file, relativePath }) => ({
|
|
1341
|
+
path: relativePath,
|
|
1342
|
+
content: await (0, import_react_utils.readFileAsText)(file)
|
|
1343
|
+
}))
|
|
1344
|
+
);
|
|
1345
|
+
await gitManager.patchFiles(
|
|
1346
|
+
repoId,
|
|
1347
|
+
{ create: createOperations },
|
|
1348
|
+
repoFilesState.ref
|
|
1349
|
+
);
|
|
1350
|
+
} catch (error) {
|
|
1351
|
+
alert(`Failed to upload files: ${error}`);
|
|
1352
|
+
} finally {
|
|
1353
|
+
setIsUploading(false);
|
|
1354
|
+
}
|
|
1355
|
+
},
|
|
1356
|
+
[gitManager, repoId, repoFilesState.ref]
|
|
1357
|
+
);
|
|
1358
|
+
return {
|
|
1359
|
+
isUploading,
|
|
1360
|
+
createFile,
|
|
1361
|
+
renameFile,
|
|
1362
|
+
deleteFiles,
|
|
1363
|
+
uploadFiles,
|
|
1364
|
+
handleFileDrop
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
// src/git/useGitFileTree.ts
|
|
1369
|
+
var import_react2 = require("react");
|
|
1370
|
+
function useGitFileTree({ repoFilesState }) {
|
|
1371
|
+
const [expandedDirs, setExpandedDirs] = (0, import_react2.useState)(
|
|
1372
|
+
() => /* @__PURE__ */ new Set()
|
|
1373
|
+
);
|
|
1374
|
+
const [tempItem, setTempItem] = (0, import_react2.useState)(void 0);
|
|
1375
|
+
const allItems = (0, import_react2.useMemo)(
|
|
1376
|
+
() => parseFilesToTree(repoFilesState.files),
|
|
1377
|
+
[repoFilesState.files]
|
|
1378
|
+
);
|
|
1379
|
+
const allItemsWithTemp = (0, import_react2.useMemo)(() => {
|
|
1380
|
+
if (!tempItem) return allItems;
|
|
1381
|
+
return [...allItems, tempItem];
|
|
1382
|
+
}, [allItems, tempItem]);
|
|
1383
|
+
const visibleItems = (0, import_react2.useMemo)(
|
|
1384
|
+
() => getVisibleItems(allItemsWithTemp, expandedDirs),
|
|
1385
|
+
[allItemsWithTemp, expandedDirs]
|
|
1386
|
+
);
|
|
1387
|
+
const getExpanded = (0, import_react2.useCallback)(
|
|
1388
|
+
(item) => {
|
|
1389
|
+
if (!item.isDirectory) return void 0;
|
|
1390
|
+
return expandedDirs.has(item.path);
|
|
1391
|
+
},
|
|
1392
|
+
[expandedDirs]
|
|
1393
|
+
);
|
|
1394
|
+
const setExpanded = (0, import_react2.useCallback)((item, expanded) => {
|
|
1395
|
+
if (!item.isDirectory) return;
|
|
1396
|
+
setExpandedDirs((prev) => {
|
|
1397
|
+
const next = new Set(prev);
|
|
1398
|
+
if (expanded) {
|
|
1399
|
+
next.add(item.path);
|
|
1400
|
+
} else {
|
|
1401
|
+
next.delete(item.path);
|
|
1402
|
+
}
|
|
1403
|
+
return next;
|
|
1404
|
+
});
|
|
1405
|
+
}, []);
|
|
1406
|
+
const toggleExpanded = (0, import_react2.useCallback)((item) => {
|
|
1407
|
+
if (!item.isDirectory) return;
|
|
1408
|
+
setExpandedDirs((prev) => {
|
|
1409
|
+
const next = new Set(prev);
|
|
1410
|
+
if (next.has(item.path)) {
|
|
1411
|
+
next.delete(item.path);
|
|
1412
|
+
} else {
|
|
1413
|
+
next.add(item.path);
|
|
1414
|
+
}
|
|
1415
|
+
return next;
|
|
1416
|
+
});
|
|
1417
|
+
}, []);
|
|
1418
|
+
const addTempItem = (0, import_react2.useCallback)(() => {
|
|
1419
|
+
const newItem = createTempFileItem();
|
|
1420
|
+
setTempItem(newItem);
|
|
1421
|
+
return newItem;
|
|
1422
|
+
}, []);
|
|
1423
|
+
const clearTempItem = (0, import_react2.useCallback)(() => {
|
|
1424
|
+
setTempItem(void 0);
|
|
1425
|
+
}, []);
|
|
1426
|
+
return {
|
|
1427
|
+
visibleItems,
|
|
1428
|
+
tempItem,
|
|
1429
|
+
getExpanded,
|
|
1430
|
+
setExpanded,
|
|
1431
|
+
toggleExpanded,
|
|
1432
|
+
addTempItem,
|
|
1433
|
+
clearTempItem
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
// src/GitFileExplorer.tsx
|
|
1438
|
+
function useDelayedTrue(condition, delayMs) {
|
|
1439
|
+
const [delayedValue, setDelayedValue] = (0, import_react3.useState)(false);
|
|
1440
|
+
(0, import_react3.useEffect)(() => {
|
|
1441
|
+
if (!condition) {
|
|
1442
|
+
setDelayedValue(false);
|
|
1443
|
+
return;
|
|
1444
|
+
}
|
|
1445
|
+
const timeout = setTimeout(() => {
|
|
1446
|
+
setDelayedValue(true);
|
|
1447
|
+
}, delayMs);
|
|
1448
|
+
return () => clearTimeout(timeout);
|
|
1449
|
+
}, [condition, delayMs]);
|
|
1450
|
+
return delayedValue;
|
|
1451
|
+
}
|
|
1452
|
+
var GitFileExplorerInner = (0, import_react3.memo)(
|
|
1453
|
+
(0, import_react3.forwardRef)(function GitFileExplorer({
|
|
1454
|
+
repoId,
|
|
1455
|
+
repoFilesState,
|
|
1456
|
+
gitManager,
|
|
1457
|
+
selectedIds: selectedIdsProp,
|
|
1458
|
+
onSelectionChange,
|
|
1459
|
+
onFileSelect,
|
|
1460
|
+
className,
|
|
1461
|
+
title = "Files"
|
|
1462
|
+
}, ref) {
|
|
1463
|
+
const [internalSelectedIds, setInternalSelectedIds] = (0, import_react3.useState)(
|
|
1464
|
+
[]
|
|
1465
|
+
);
|
|
1466
|
+
const selectedIds = selectedIdsProp ?? internalSelectedIds;
|
|
1467
|
+
const baseSetSelectedIds = onSelectionChange ?? setInternalSelectedIds;
|
|
1468
|
+
const dropTargetRef = (0, import_react3.useRef)(null);
|
|
1469
|
+
const collectionRef = (0, import_react3.useRef)(null);
|
|
1470
|
+
const openConfirmationDialog = (0, import_noya_designsystem.useOpenConfirmationDialog)();
|
|
1471
|
+
const {
|
|
1472
|
+
visibleItems,
|
|
1473
|
+
getExpanded,
|
|
1474
|
+
setExpanded,
|
|
1475
|
+
toggleExpanded,
|
|
1476
|
+
addTempItem,
|
|
1477
|
+
clearTempItem
|
|
1478
|
+
} = useGitFileTree({ repoFilesState });
|
|
1479
|
+
const setSelectedIds = (0, import_react3.useCallback)(
|
|
1480
|
+
(ids) => {
|
|
1481
|
+
baseSetSelectedIds(ids);
|
|
1482
|
+
if (ids.length === 1) {
|
|
1483
|
+
const item = visibleItems.find((i) => i.id === ids[0]);
|
|
1484
|
+
if (item && !item.isDirectory) {
|
|
1485
|
+
onFileSelect?.(item.path);
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
},
|
|
1489
|
+
[baseSetSelectedIds, visibleItems, onFileSelect]
|
|
1490
|
+
);
|
|
1491
|
+
const {
|
|
1492
|
+
isUploading,
|
|
1493
|
+
renameFile,
|
|
1494
|
+
deleteFiles,
|
|
1495
|
+
uploadFiles,
|
|
1496
|
+
handleFileDrop
|
|
1497
|
+
} = useGitFileOperations({ repoId, repoFilesState, gitManager });
|
|
1498
|
+
const { dropTargetProps, isDropTargetActive } = (0, import_react_utils2.useFileDropTarget)(
|
|
1499
|
+
dropTargetRef,
|
|
1500
|
+
handleFileDrop
|
|
1501
|
+
);
|
|
1502
|
+
const handleAddFile = (0, import_react3.useCallback)(() => {
|
|
1503
|
+
const newItem = addTempItem();
|
|
1504
|
+
setTimeout(() => {
|
|
1505
|
+
collectionRef.current?.editName(newItem.id);
|
|
1506
|
+
}, 50);
|
|
1507
|
+
}, [addTempItem]);
|
|
1508
|
+
const handleStartRename = (0, import_react3.useCallback)((itemId) => {
|
|
1509
|
+
collectionRef.current?.editName(itemId);
|
|
1510
|
+
}, []);
|
|
1511
|
+
const handleRename = (0, import_react3.useCallback)(
|
|
1512
|
+
async (item, newName) => {
|
|
1513
|
+
if (isTempItem(item)) {
|
|
1514
|
+
clearTempItem();
|
|
1515
|
+
if (!newName) return;
|
|
1516
|
+
}
|
|
1517
|
+
await renameFile(item, newName);
|
|
1518
|
+
},
|
|
1519
|
+
[renameFile, clearTempItem]
|
|
1520
|
+
);
|
|
1521
|
+
const handleDelete = (0, import_react3.useCallback)(
|
|
1522
|
+
async (items) => {
|
|
1523
|
+
if (items.length === 0) return;
|
|
1524
|
+
const fileCount = items.filter((item) => !item.isDirectory).length;
|
|
1525
|
+
const dirCount = items.filter((item) => item.isDirectory).length;
|
|
1526
|
+
let description;
|
|
1527
|
+
if (dirCount > 0 && fileCount > 0) {
|
|
1528
|
+
description = `Are you sure you want to delete ${fileCount} file(s) and ${dirCount} folder(s)? This action cannot be undone.`;
|
|
1529
|
+
} else if (dirCount > 0) {
|
|
1530
|
+
description = `Are you sure you want to delete ${dirCount} folder(s) and all their contents? This action cannot be undone.`;
|
|
1531
|
+
} else {
|
|
1532
|
+
description = `Are you sure you want to delete ${fileCount} file(s)? This action cannot be undone.`;
|
|
1533
|
+
}
|
|
1534
|
+
const confirmed = await openConfirmationDialog({
|
|
1535
|
+
title: "Delete",
|
|
1536
|
+
description
|
|
1537
|
+
});
|
|
1538
|
+
if (!confirmed) return;
|
|
1539
|
+
await deleteFiles(items);
|
|
1540
|
+
setSelectedIds([]);
|
|
1541
|
+
},
|
|
1542
|
+
[deleteFiles, setSelectedIds, openConfirmationDialog]
|
|
1543
|
+
);
|
|
1544
|
+
const handleDoubleClick = (0, import_react3.useCallback)(
|
|
1545
|
+
(itemId) => {
|
|
1546
|
+
const item = visibleItems.find((i) => i.id === itemId);
|
|
1547
|
+
if (!item) return;
|
|
1548
|
+
if (item.isDirectory) {
|
|
1549
|
+
toggleExpanded(item);
|
|
1550
|
+
} else {
|
|
1551
|
+
onFileSelect?.(item.path);
|
|
1552
|
+
}
|
|
1553
|
+
},
|
|
1554
|
+
[visibleItems, toggleExpanded, onFileSelect]
|
|
1555
|
+
);
|
|
1556
|
+
const headerMenuItems = (0, import_react3.useMemo)(
|
|
1557
|
+
() => (0, import_noya_designsystem.createSectionedMenu)([
|
|
1558
|
+
{
|
|
1559
|
+
title: "New File",
|
|
1560
|
+
value: "newFile",
|
|
1561
|
+
icon: /* @__PURE__ */ import_react3.default.createElement(import_noya_icons.PlusIcon, null)
|
|
1562
|
+
},
|
|
1563
|
+
{
|
|
1564
|
+
title: "Upload Files",
|
|
1565
|
+
value: "uploadFiles",
|
|
1566
|
+
icon: /* @__PURE__ */ import_react3.default.createElement(import_noya_icons.UploadIcon, null)
|
|
1567
|
+
}
|
|
1568
|
+
]),
|
|
1569
|
+
[]
|
|
1570
|
+
);
|
|
1571
|
+
const handleHeaderMenuAction = (0, import_react3.useCallback)(
|
|
1572
|
+
(action) => {
|
|
1573
|
+
switch (action) {
|
|
1574
|
+
case "newFile":
|
|
1575
|
+
handleAddFile();
|
|
1576
|
+
break;
|
|
1577
|
+
case "uploadFiles":
|
|
1578
|
+
uploadFiles();
|
|
1579
|
+
break;
|
|
1580
|
+
}
|
|
1581
|
+
},
|
|
1582
|
+
[handleAddFile, uploadFiles]
|
|
1583
|
+
);
|
|
1584
|
+
const handleMenuAction = (0, import_react3.useCallback)(
|
|
1585
|
+
(action, items) => {
|
|
1586
|
+
switch (action) {
|
|
1587
|
+
case "addFile":
|
|
1588
|
+
handleAddFile();
|
|
1589
|
+
break;
|
|
1590
|
+
case "rename":
|
|
1591
|
+
if (items.length === 1) {
|
|
1592
|
+
handleStartRename(items[0].id);
|
|
1593
|
+
}
|
|
1594
|
+
break;
|
|
1595
|
+
case "delete":
|
|
1596
|
+
handleDelete(items);
|
|
1597
|
+
break;
|
|
1598
|
+
}
|
|
1599
|
+
},
|
|
1600
|
+
[handleAddFile, handleStartRename, handleDelete]
|
|
1601
|
+
);
|
|
1602
|
+
const menuItems = (0, import_react3.useMemo)(() => {
|
|
1603
|
+
const singleSelected = selectedIds.length === 1;
|
|
1604
|
+
const hasSelection = selectedIds.length > 0;
|
|
1605
|
+
const selectedItem = singleSelected ? visibleItems.find((item) => selectedIds.includes(item.id)) : void 0;
|
|
1606
|
+
const isFile = selectedItem && !selectedItem.isDirectory;
|
|
1607
|
+
return (0, import_noya_designsystem.createSectionedMenu)(
|
|
1608
|
+
[
|
|
1609
|
+
{
|
|
1610
|
+
title: "Add File",
|
|
1611
|
+
value: "addFile",
|
|
1612
|
+
icon: /* @__PURE__ */ import_react3.default.createElement(import_noya_icons.PlusIcon, null)
|
|
1613
|
+
}
|
|
1614
|
+
],
|
|
1615
|
+
[
|
|
1616
|
+
singleSelected && isFile && {
|
|
1617
|
+
title: "Rename",
|
|
1618
|
+
value: "rename",
|
|
1619
|
+
icon: /* @__PURE__ */ import_react3.default.createElement(import_noya_icons.InputIcon, null)
|
|
1620
|
+
},
|
|
1621
|
+
hasSelection && {
|
|
1622
|
+
title: "Delete",
|
|
1623
|
+
value: "delete",
|
|
1624
|
+
icon: /* @__PURE__ */ import_react3.default.createElement(import_noya_icons.TrashIcon, null)
|
|
1625
|
+
}
|
|
1626
|
+
]
|
|
1627
|
+
);
|
|
1628
|
+
}, [selectedIds, visibleItems]);
|
|
1629
|
+
(0, import_react3.useImperativeHandle)(ref, () => ({
|
|
1630
|
+
addFile: handleAddFile,
|
|
1631
|
+
delete: (ids) => {
|
|
1632
|
+
const items = visibleItems.filter((item) => ids.includes(item.id));
|
|
1633
|
+
handleDelete(items);
|
|
1634
|
+
},
|
|
1635
|
+
rename: (id) => {
|
|
1636
|
+
handleStartRename(id);
|
|
1637
|
+
}
|
|
1638
|
+
}));
|
|
1639
|
+
const isRefreshing = repoFilesState.fetchState === "refreshing";
|
|
1640
|
+
const isLoading = repoFilesState.fetchState === "loading";
|
|
1641
|
+
const showLoading = useDelayedTrue(isLoading, 500);
|
|
1642
|
+
const renderEmptyState = (0, import_react3.useCallback)(() => {
|
|
1643
|
+
const hasError = !!repoFilesState.error;
|
|
1644
|
+
let content = null;
|
|
1645
|
+
if (isLoading && showLoading) {
|
|
1646
|
+
content = /* @__PURE__ */ import_react3.default.createElement(import_noya_designsystem.Small, null, "Loading files...");
|
|
1647
|
+
} else if (isLoading) {
|
|
1648
|
+
content = null;
|
|
1649
|
+
} else if (hasError) {
|
|
1650
|
+
content = /* @__PURE__ */ import_react3.default.createElement(import_noya_designsystem.Small, null, "Error: ", repoFilesState.error);
|
|
1651
|
+
} else {
|
|
1652
|
+
content = /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement(import_noya_designsystem.Small, null, "No files yet"), /* @__PURE__ */ import_react3.default.createElement(import_noya_designsystem.Button, { onClick: handleAddFile }, "Add a file"));
|
|
1653
|
+
}
|
|
1654
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "n-mx-3 n-flex-1 n-flex n-flex-col n-items-center n-justify-center n-gap-2" }, content);
|
|
1655
|
+
}, [repoFilesState.error, handleAddFile, isLoading, showLoading]);
|
|
1656
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
1657
|
+
import_noya_designsystem.Section,
|
|
1658
|
+
{
|
|
1659
|
+
title,
|
|
1660
|
+
className: (0, import_noya_designsystem.cx)("n-px-3", className),
|
|
1661
|
+
right: /* @__PURE__ */ import_react3.default.createElement("div", { className: "n-flex n-items-center n-gap-1" }, isRefreshing && /* @__PURE__ */ import_react3.default.createElement(import_noya_designsystem.Small, { color: "textDisabled" }, "Syncing..."), isUploading && /* @__PURE__ */ import_react3.default.createElement(import_noya_designsystem.Small, { color: "textDisabled" }, "Uploading..."), /* @__PURE__ */ import_react3.default.createElement(
|
|
1662
|
+
import_noya_designsystem.DropdownMenu,
|
|
1663
|
+
{
|
|
1664
|
+
items: headerMenuItems,
|
|
1665
|
+
onSelect: handleHeaderMenuAction
|
|
1666
|
+
},
|
|
1667
|
+
/* @__PURE__ */ import_react3.default.createElement(import_noya_designsystem.IconButton, { iconName: "DotsVerticalIcon" })
|
|
1668
|
+
))
|
|
1669
|
+
},
|
|
1670
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
1671
|
+
"div",
|
|
1672
|
+
{
|
|
1673
|
+
ref: dropTargetRef,
|
|
1674
|
+
className: (0, import_noya_designsystem.cx)(
|
|
1675
|
+
"n-flex n-flex-col n-flex-1 -n-mx-3",
|
|
1676
|
+
isDropTargetActive && "n-bg-blue-500/10 n-ring-2 n-ring-blue-500 n-ring-inset"
|
|
1677
|
+
),
|
|
1678
|
+
...dropTargetProps
|
|
1679
|
+
},
|
|
1680
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
1681
|
+
import_noya_designsystem.List,
|
|
1682
|
+
{
|
|
1683
|
+
ref: collectionRef,
|
|
1684
|
+
className: "n-flex-1",
|
|
1685
|
+
scrollable: true,
|
|
1686
|
+
expandable: true,
|
|
1687
|
+
renamable: true,
|
|
1688
|
+
size: "small",
|
|
1689
|
+
items: visibleItems,
|
|
1690
|
+
getId: (item) => item.id,
|
|
1691
|
+
getName: (item) => isTempItem(item) ? "" : item.name,
|
|
1692
|
+
getDepth: (item) => item.depth,
|
|
1693
|
+
getExpanded,
|
|
1694
|
+
setExpanded,
|
|
1695
|
+
getRenamable: (item) => !item.isDirectory,
|
|
1696
|
+
getPlaceholder: () => "Enter file name",
|
|
1697
|
+
selectedIds,
|
|
1698
|
+
onSelectionChange: setSelectedIds,
|
|
1699
|
+
onDoubleClickItem: handleDoubleClick,
|
|
1700
|
+
onRename: handleRename,
|
|
1701
|
+
menuItems,
|
|
1702
|
+
onSelectMenuItem: handleMenuAction,
|
|
1703
|
+
renderEmptyState,
|
|
1704
|
+
renameSelectsBeforeDot: true,
|
|
1705
|
+
renderThumbnail: ({ item, selected }) => /* @__PURE__ */ import_react3.default.createElement(
|
|
1706
|
+
import_noya_designsystem.MediaThumbnail,
|
|
1707
|
+
{
|
|
1708
|
+
iconName: item.isDirectory ? "FolderIcon" : void 0,
|
|
1709
|
+
fileName: item.isDirectory ? void 0 : item.name,
|
|
1710
|
+
selected,
|
|
1711
|
+
size: "small"
|
|
1712
|
+
}
|
|
1713
|
+
)
|
|
1714
|
+
}
|
|
1715
|
+
)
|
|
1716
|
+
)
|
|
1717
|
+
);
|
|
1718
|
+
})
|
|
1719
|
+
);
|
|
1720
|
+
var GitFileExplorer2 = (0, import_react3.memo)(
|
|
1721
|
+
(0, import_react3.forwardRef)(function GitFileExplorer3(props, ref) {
|
|
1722
|
+
if (!props.repoFilesState) {
|
|
1723
|
+
return /* @__PURE__ */ import_react3.default.createElement(import_noya_designsystem.Section, { title: props.title, className: (0, import_noya_designsystem.cx)("n-px-3", props.className) }, null);
|
|
1724
|
+
}
|
|
1725
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
1726
|
+
GitFileExplorerInner,
|
|
1727
|
+
{
|
|
1728
|
+
...props,
|
|
1729
|
+
repoFilesState: props.repoFilesState,
|
|
1730
|
+
ref
|
|
1731
|
+
}
|
|
1732
|
+
);
|
|
1733
|
+
})
|
|
1734
|
+
);
|
|
1735
|
+
|
|
1736
|
+
// src/MediaCollection.tsx
|
|
1737
|
+
var import_noya_designsystem2 = require("@noya-app/noya-designsystem");
|
|
1738
|
+
var import_noya_icons2 = require("@noya-app/noya-icons");
|
|
1739
|
+
var import_noya_multiplayer_react = require("@noya-app/noya-multiplayer-react");
|
|
1740
|
+
var import_noya_utils2 = require("@noya-app/noya-utils");
|
|
1741
|
+
var import_react_utils3 = require("@noya-app/react-utils");
|
|
1742
|
+
var import_browser_fs_access2 = require("browser-fs-access");
|
|
1743
|
+
var import_react4 = require("react");
|
|
1161
1744
|
|
|
1162
1745
|
// src/utils/mediaItemTree.ts
|
|
1163
1746
|
var import_noya_utils = require("@noya-app/noya-utils");
|
|
@@ -1242,7 +1825,7 @@ var createMediaItemTree = (mediaMap) => {
|
|
|
1242
1825
|
|
|
1243
1826
|
// src/MediaCollection.tsx
|
|
1244
1827
|
var import_imfs4 = require("imfs");
|
|
1245
|
-
var
|
|
1828
|
+
var import_react5 = __toESM(require("react"));
|
|
1246
1829
|
|
|
1247
1830
|
// src/utils/files.ts
|
|
1248
1831
|
var import_imfs3 = require("imfs");
|
|
@@ -1252,7 +1835,7 @@ var import_tree_visit3 = __toESM(require_lib());
|
|
|
1252
1835
|
var import_noya_schemas = require("@noya-app/noya-schemas");
|
|
1253
1836
|
var import_imfs2 = require("imfs");
|
|
1254
1837
|
var import_tree_visit2 = __toESM(require_lib());
|
|
1255
|
-
var
|
|
1838
|
+
var getVisibleItems2 = ({
|
|
1256
1839
|
expandedMap,
|
|
1257
1840
|
fileKindFilter,
|
|
1258
1841
|
rootItemId,
|
|
@@ -1697,7 +2280,7 @@ function encodeFileContentForThumbnail(pathProp, item) {
|
|
|
1697
2280
|
}
|
|
1698
2281
|
return void 0;
|
|
1699
2282
|
}
|
|
1700
|
-
var MediaThumbnailInternal = (0,
|
|
2283
|
+
var MediaThumbnailInternal = (0, import_react_utils3.memoGeneric)(
|
|
1701
2284
|
({
|
|
1702
2285
|
item,
|
|
1703
2286
|
selected,
|
|
@@ -1727,8 +2310,8 @@ var MediaThumbnailInternal = (0, import_react_utils.memoGeneric)(
|
|
|
1727
2310
|
}
|
|
1728
2311
|
const fileName = pathProp ? import_imfs4.path.basename(pathProp) : void 0;
|
|
1729
2312
|
const dimensions = width && height ? { width, height } : void 0;
|
|
1730
|
-
return /* @__PURE__ */
|
|
1731
|
-
|
|
2313
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
2314
|
+
import_noya_designsystem2.MediaThumbnail,
|
|
1732
2315
|
{
|
|
1733
2316
|
contentType,
|
|
1734
2317
|
iconName: isRoot ? "HomeIcon" : isFolder ? "FolderIcon" : void 0,
|
|
@@ -1742,8 +2325,8 @@ var MediaThumbnailInternal = (0, import_react_utils.memoGeneric)(
|
|
|
1742
2325
|
);
|
|
1743
2326
|
}
|
|
1744
2327
|
);
|
|
1745
|
-
var MediaCollection = (0,
|
|
1746
|
-
(0,
|
|
2328
|
+
var MediaCollection = (0, import_react4.memo)(
|
|
2329
|
+
(0, import_react4.forwardRef)(function MediaCollection2({
|
|
1747
2330
|
sortableId,
|
|
1748
2331
|
onSelectionChange,
|
|
1749
2332
|
selectedIds: selectedIdsProp,
|
|
@@ -1774,35 +2357,35 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1774
2357
|
onDidDeleteItems,
|
|
1775
2358
|
onAssetsUploaded
|
|
1776
2359
|
}, ref) {
|
|
1777
|
-
const setMedia = (0,
|
|
2360
|
+
const setMedia = (0, import_react4.useCallback)(
|
|
1778
2361
|
(...args) => {
|
|
1779
2362
|
setMediaProp?.(...args);
|
|
1780
2363
|
},
|
|
1781
2364
|
[setMediaProp]
|
|
1782
2365
|
);
|
|
1783
|
-
const tree = (0,
|
|
1784
|
-
const [tempItem, setTempItem] = (0,
|
|
2366
|
+
const tree = (0, import_react4.useMemo)(() => createMediaItemTree(media), [media]);
|
|
2367
|
+
const [tempItem, setTempItem] = (0, import_react4.useState)(
|
|
1785
2368
|
void 0
|
|
1786
2369
|
);
|
|
1787
|
-
const mediaWithTempItem = (0,
|
|
2370
|
+
const mediaWithTempItem = (0, import_react4.useMemo)(
|
|
1788
2371
|
() => ({
|
|
1789
2372
|
...media,
|
|
1790
2373
|
...tempItem ? { [tempItem[0]]: tempItem[1] } : {}
|
|
1791
2374
|
}),
|
|
1792
2375
|
[media, tempItem]
|
|
1793
2376
|
);
|
|
1794
|
-
const treeWithTempItem = (0,
|
|
2377
|
+
const treeWithTempItem = (0, import_react4.useMemo)(
|
|
1795
2378
|
() => createMediaItemTree(mediaWithTempItem),
|
|
1796
2379
|
[mediaWithTempItem]
|
|
1797
2380
|
);
|
|
1798
|
-
const temp = (0,
|
|
2381
|
+
const temp = (0, import_react4.useMemo)(
|
|
1799
2382
|
() => ({
|
|
1800
2383
|
media: mediaWithTempItem,
|
|
1801
2384
|
tree: treeWithTempItem
|
|
1802
2385
|
}),
|
|
1803
2386
|
[mediaWithTempItem, treeWithTempItem]
|
|
1804
2387
|
);
|
|
1805
|
-
const [selectedIds, setSelectedIds] = (0,
|
|
2388
|
+
const [selectedIds, setSelectedIds] = (0, import_react_utils3.useControlledOrUncontrolled)(
|
|
1806
2389
|
{
|
|
1807
2390
|
defaultValue: [],
|
|
1808
2391
|
value: selectedIdsProp,
|
|
@@ -1811,8 +2394,8 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1811
2394
|
);
|
|
1812
2395
|
const assetManager = (0, import_noya_multiplayer_react.useAssetManager)();
|
|
1813
2396
|
const assets = (0, import_noya_multiplayer_react.useAssets)();
|
|
1814
|
-
const [expandedMap, setExpandedMap] = (0,
|
|
1815
|
-
const visibleItems = (0,
|
|
2397
|
+
const [expandedMap, setExpandedMap] = (0, import_react4.useState)({});
|
|
2398
|
+
const visibleItems = (0, import_react4.useMemo)(
|
|
1816
2399
|
() => mediaGetVisibleItems({
|
|
1817
2400
|
expandedMap,
|
|
1818
2401
|
fileKindFilter,
|
|
@@ -1830,12 +2413,12 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1830
2413
|
showRootItem
|
|
1831
2414
|
]
|
|
1832
2415
|
);
|
|
1833
|
-
const depthMap = (0,
|
|
2416
|
+
const depthMap = (0, import_react4.useMemo)(
|
|
1834
2417
|
() => mediaGetDepthMap(rootMediaItem, treeWithTempItem, showAllDescendants),
|
|
1835
2418
|
[treeWithTempItem, showAllDescendants]
|
|
1836
2419
|
);
|
|
1837
|
-
const collectionRef = (0,
|
|
1838
|
-
const selectedMediaItems = (0,
|
|
2420
|
+
const collectionRef = (0, import_react4.useRef)(null);
|
|
2421
|
+
const selectedMediaItems = (0, import_react4.useMemo)(
|
|
1839
2422
|
() => treeWithTempItem.mediaItemsWithRoot.filter(
|
|
1840
2423
|
(item) => selectedIds.includes(item.id)
|
|
1841
2424
|
),
|
|
@@ -1856,12 +2439,12 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1856
2439
|
if (!itemPath || !firstSelectedPath) return false;
|
|
1857
2440
|
return itemPath.startsWith(import_imfs4.path.dirname(firstSelectedPath));
|
|
1858
2441
|
});
|
|
1859
|
-
(0,
|
|
2442
|
+
(0, import_react4.useEffect)(() => {
|
|
1860
2443
|
if (initialExpanded) {
|
|
1861
2444
|
setExpandedMap(initialExpanded);
|
|
1862
2445
|
}
|
|
1863
2446
|
}, [initialExpanded]);
|
|
1864
|
-
const getExpanded = (0,
|
|
2447
|
+
const getExpanded = (0, import_react4.useCallback)(
|
|
1865
2448
|
(item) => {
|
|
1866
2449
|
if (!expandable) return void 0;
|
|
1867
2450
|
if (item.kind !== "folder") return void 0;
|
|
@@ -1870,8 +2453,8 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1870
2453
|
},
|
|
1871
2454
|
[expandedMap, expandable]
|
|
1872
2455
|
);
|
|
1873
|
-
const openConfirmationDialog = (0,
|
|
1874
|
-
const handleDelete = (0,
|
|
2456
|
+
const openConfirmationDialog = (0, import_noya_designsystem2.useOpenConfirmationDialog)();
|
|
2457
|
+
const handleDelete = (0, import_react4.useCallback)(
|
|
1875
2458
|
async (selectedIds2) => {
|
|
1876
2459
|
const ok = await openConfirmationDialog({
|
|
1877
2460
|
title: "Delete items",
|
|
@@ -1904,7 +2487,7 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1904
2487
|
openConfirmationDialog
|
|
1905
2488
|
]
|
|
1906
2489
|
);
|
|
1907
|
-
const onRename = (0,
|
|
2490
|
+
const onRename = (0, import_react4.useCallback)(
|
|
1908
2491
|
(selectedItem, newName) => {
|
|
1909
2492
|
if (!renamable) return;
|
|
1910
2493
|
const selectedItemPath = treeWithTempItem.idToPathMap.get(
|
|
@@ -1934,7 +2517,7 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1934
2517
|
},
|
|
1935
2518
|
[renamable, setMedia, temp.media, temp.tree, treeWithTempItem.idToPathMap]
|
|
1936
2519
|
);
|
|
1937
|
-
const handleAddFolder = (0,
|
|
2520
|
+
const handleAddFolder = (0, import_react4.useCallback)(
|
|
1938
2521
|
(currentFolderId) => {
|
|
1939
2522
|
const newFolder = createMediaFolder();
|
|
1940
2523
|
const currentFolderPath = tree.idToPathMap.get(currentFolderId);
|
|
@@ -1949,7 +2532,7 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1949
2532
|
},
|
|
1950
2533
|
[tree]
|
|
1951
2534
|
);
|
|
1952
|
-
const handleAddFile = (0,
|
|
2535
|
+
const handleAddFile = (0, import_react4.useCallback)(
|
|
1953
2536
|
(currentFolderId) => {
|
|
1954
2537
|
const newFile = createMediaFile({
|
|
1955
2538
|
content: "",
|
|
@@ -1969,7 +2552,7 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1969
2552
|
},
|
|
1970
2553
|
[tree.idToPathMap]
|
|
1971
2554
|
);
|
|
1972
|
-
const handleMoveUpAFolder = (0,
|
|
2555
|
+
const handleMoveUpAFolder = (0, import_react4.useCallback)(
|
|
1973
2556
|
(selectedIds2) => {
|
|
1974
2557
|
const newMedia = mediaMoveUpAFolder({
|
|
1975
2558
|
tree,
|
|
@@ -1981,11 +2564,11 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
1981
2564
|
},
|
|
1982
2565
|
[media, tree, setMedia]
|
|
1983
2566
|
);
|
|
1984
|
-
const [isUploading, setIsUploading] = (0,
|
|
1985
|
-
const handleUpload = (0,
|
|
2567
|
+
const [isUploading, setIsUploading] = (0, import_react4.useState)(false);
|
|
2568
|
+
const handleUpload = (0, import_react4.useCallback)(
|
|
1986
2569
|
async (selectedId) => {
|
|
1987
2570
|
try {
|
|
1988
|
-
const files = await (0,
|
|
2571
|
+
const files = await (0, import_browser_fs_access2.fileOpen)({ multiple: true });
|
|
1989
2572
|
if (!files || !Array.isArray(files) || files.length === 0) return;
|
|
1990
2573
|
const parentPath = tree.idToPathMap.get(selectedId);
|
|
1991
2574
|
if (!parentPath) return;
|
|
@@ -2022,18 +2605,18 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2022
2605
|
},
|
|
2023
2606
|
[tree.idToPathMap, setMedia, media, assetManager, onAssetsUploaded]
|
|
2024
2607
|
);
|
|
2025
|
-
const handleDownload = (0,
|
|
2608
|
+
const handleDownload = (0, import_react4.useCallback)(
|
|
2026
2609
|
async (selectedItems) => {
|
|
2027
2610
|
const downloadPromises = selectedItems.filter((item) => item.kind === "asset").map(async (item) => {
|
|
2028
2611
|
const asset = assets.find((a) => a.stableId === item.assetId) ?? assets.find((a) => a.id === item.assetId);
|
|
2029
2612
|
if (!asset?.url) return;
|
|
2030
|
-
return (0,
|
|
2613
|
+
return (0, import_react_utils3.downloadUrl)(asset.url, tree.getNameForId(item.id));
|
|
2031
2614
|
});
|
|
2032
2615
|
await Promise.all(downloadPromises);
|
|
2033
2616
|
},
|
|
2034
2617
|
[assets, tree]
|
|
2035
2618
|
);
|
|
2036
|
-
const handlePreview = (0,
|
|
2619
|
+
const handlePreview = (0, import_react4.useCallback)(
|
|
2037
2620
|
async (selectedItems) => {
|
|
2038
2621
|
const previewPromises = selectedItems.filter((item) => item.kind === "asset").map(async (item) => {
|
|
2039
2622
|
const asset = assets.find((a) => a.stableId === item.assetId) ?? assets.find((a) => a.id === item.assetId);
|
|
@@ -2044,10 +2627,10 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2044
2627
|
},
|
|
2045
2628
|
[assets]
|
|
2046
2629
|
);
|
|
2047
|
-
const handleReplace = (0,
|
|
2630
|
+
const handleReplace = (0, import_react4.useCallback)(
|
|
2048
2631
|
async (selectedItem) => {
|
|
2049
2632
|
try {
|
|
2050
|
-
const file = await (0,
|
|
2633
|
+
const file = await (0, import_browser_fs_access2.fileOpen)();
|
|
2051
2634
|
if (!file) return;
|
|
2052
2635
|
const created = await assetManager.create(file);
|
|
2053
2636
|
const assetStableId = created.id;
|
|
@@ -2073,13 +2656,13 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2073
2656
|
},
|
|
2074
2657
|
[media, setMedia, assetManager, tree]
|
|
2075
2658
|
);
|
|
2076
|
-
const handleRename = (0,
|
|
2659
|
+
const handleRename = (0, import_react4.useCallback)(
|
|
2077
2660
|
(selectedItemId) => {
|
|
2078
2661
|
collectionRef.current?.editName(selectedItemId);
|
|
2079
2662
|
},
|
|
2080
2663
|
[collectionRef]
|
|
2081
2664
|
);
|
|
2082
|
-
const handleMoveMediaInsideFolder = (0,
|
|
2665
|
+
const handleMoveMediaInsideFolder = (0, import_react4.useCallback)(
|
|
2083
2666
|
(sourceItem, targetItem) => {
|
|
2084
2667
|
const newMedia = mediaMoveMediaInsideFolder({
|
|
2085
2668
|
sourceItemIds: [sourceItem.id],
|
|
@@ -2097,52 +2680,52 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2097
2680
|
},
|
|
2098
2681
|
[media, setMedia, tree]
|
|
2099
2682
|
);
|
|
2100
|
-
const assetContextMenuItems = (0,
|
|
2101
|
-
return (0,
|
|
2683
|
+
const assetContextMenuItems = (0, import_react4.useMemo)(() => {
|
|
2684
|
+
return (0, import_noya_designsystem2.createSectionedMenu)(
|
|
2102
2685
|
[
|
|
2103
2686
|
!rootSelected && singleItemSelected && {
|
|
2104
2687
|
title: "Rename",
|
|
2105
2688
|
value: "rename",
|
|
2106
|
-
icon: /* @__PURE__ */
|
|
2689
|
+
icon: /* @__PURE__ */ import_react5.default.createElement(import_noya_icons2.InputIcon, null)
|
|
2107
2690
|
},
|
|
2108
2691
|
onlySingleAssetSelected && {
|
|
2109
2692
|
title: "Replace",
|
|
2110
2693
|
value: "replace",
|
|
2111
|
-
icon: /* @__PURE__ */
|
|
2694
|
+
icon: /* @__PURE__ */ import_react5.default.createElement(import_noya_icons2.UpdateIcon, null)
|
|
2112
2695
|
},
|
|
2113
2696
|
!rootSelected && {
|
|
2114
2697
|
title: "Delete",
|
|
2115
2698
|
value: "delete",
|
|
2116
|
-
icon: /* @__PURE__ */
|
|
2699
|
+
icon: /* @__PURE__ */ import_react5.default.createElement(import_noya_icons2.TrashIcon, null)
|
|
2117
2700
|
}
|
|
2118
2701
|
],
|
|
2119
2702
|
[
|
|
2120
2703
|
onlySingleFolderSelected && {
|
|
2121
2704
|
title: "Upload Files",
|
|
2122
2705
|
value: "upload",
|
|
2123
|
-
icon: /* @__PURE__ */
|
|
2706
|
+
icon: /* @__PURE__ */ import_react5.default.createElement(import_noya_icons2.UploadIcon, null)
|
|
2124
2707
|
},
|
|
2125
2708
|
onlySingleFolderSelected && {
|
|
2126
2709
|
title: "Add Folder",
|
|
2127
2710
|
value: "addFolder",
|
|
2128
|
-
icon: /* @__PURE__ */
|
|
2711
|
+
icon: /* @__PURE__ */ import_react5.default.createElement(import_noya_icons2.FolderIcon, null)
|
|
2129
2712
|
},
|
|
2130
2713
|
onlyAssetsSelected && tree.mediaItemsWithRoot.length > 0 && {
|
|
2131
2714
|
title: "Download",
|
|
2132
2715
|
value: "download",
|
|
2133
|
-
icon: /* @__PURE__ */
|
|
2716
|
+
icon: /* @__PURE__ */ import_react5.default.createElement(import_noya_icons2.DownloadIcon, null)
|
|
2134
2717
|
},
|
|
2135
2718
|
onlySingleAssetSelected && {
|
|
2136
2719
|
title: "Preview",
|
|
2137
2720
|
value: "preview",
|
|
2138
|
-
icon: /* @__PURE__ */
|
|
2721
|
+
icon: /* @__PURE__ */ import_react5.default.createElement(import_noya_icons2.OpenInNewWindowIcon, null)
|
|
2139
2722
|
}
|
|
2140
2723
|
],
|
|
2141
2724
|
[
|
|
2142
2725
|
!rootSelected && sameParentSelected && {
|
|
2143
2726
|
title: "Move up a folder",
|
|
2144
2727
|
value: "move",
|
|
2145
|
-
icon: /* @__PURE__ */
|
|
2728
|
+
icon: /* @__PURE__ */ import_react5.default.createElement(import_noya_icons2.ResetIcon, null)
|
|
2146
2729
|
}
|
|
2147
2730
|
]
|
|
2148
2731
|
);
|
|
@@ -2155,7 +2738,7 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2155
2738
|
tree.mediaItemsWithRoot.length,
|
|
2156
2739
|
sameParentSelected
|
|
2157
2740
|
]);
|
|
2158
|
-
const handleMenuAction = (0,
|
|
2741
|
+
const handleMenuAction = (0, import_react4.useCallback)(
|
|
2159
2742
|
async (action, selectedItems) => {
|
|
2160
2743
|
if (selectedItems.length === 0) return;
|
|
2161
2744
|
switch (action) {
|
|
@@ -2197,7 +2780,7 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2197
2780
|
handleMoveUpAFolder
|
|
2198
2781
|
]
|
|
2199
2782
|
);
|
|
2200
|
-
const handleSetExpanded = (0,
|
|
2783
|
+
const handleSetExpanded = (0, import_react4.useCallback)(
|
|
2201
2784
|
(item, expanded) => {
|
|
2202
2785
|
setExpandedMap(
|
|
2203
2786
|
(prev) => mediaUpdateExpandedMap({
|
|
@@ -2211,13 +2794,13 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2211
2794
|
},
|
|
2212
2795
|
[expandable, tree]
|
|
2213
2796
|
);
|
|
2214
|
-
const renderAction = (0,
|
|
2797
|
+
const renderAction = (0, import_react4.useMemo)(() => {
|
|
2215
2798
|
if (renderActionProp) return renderActionProp;
|
|
2216
2799
|
return ({
|
|
2217
2800
|
selected,
|
|
2218
2801
|
onOpenChange
|
|
2219
|
-
}) => /* @__PURE__ */
|
|
2220
|
-
|
|
2802
|
+
}) => /* @__PURE__ */ import_react5.default.createElement(
|
|
2803
|
+
import_noya_designsystem2.ActionMenu,
|
|
2221
2804
|
{
|
|
2222
2805
|
menuItems: assetContextMenuItems,
|
|
2223
2806
|
onSelect: (action) => handleMenuAction(action, selectedMediaItems),
|
|
@@ -2225,8 +2808,8 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2225
2808
|
onOpenChange,
|
|
2226
2809
|
variant: viewType === "grid" ? "normal" : "bare",
|
|
2227
2810
|
style: {
|
|
2228
|
-
backgroundColor: selected ?
|
|
2229
|
-
color: selected ?
|
|
2811
|
+
backgroundColor: selected ? import_noya_designsystem2.cssVars.colors.selectedListItemBackground : "transparent",
|
|
2812
|
+
color: selected ? import_noya_designsystem2.cssVars.colors.selectedListItemText : void 0
|
|
2230
2813
|
}
|
|
2231
2814
|
}
|
|
2232
2815
|
);
|
|
@@ -2237,7 +2820,7 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2237
2820
|
selectedMediaItems,
|
|
2238
2821
|
viewType
|
|
2239
2822
|
]);
|
|
2240
|
-
(0,
|
|
2823
|
+
(0, import_react4.useImperativeHandle)(ref, () => ({
|
|
2241
2824
|
upload: (selectedId) => handleUpload(selectedId),
|
|
2242
2825
|
delete: handleDelete,
|
|
2243
2826
|
download: handleDownload,
|
|
@@ -2250,12 +2833,12 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2250
2833
|
moveMediaInsideFolder: handleMoveMediaInsideFolder,
|
|
2251
2834
|
getItemAtIndex: (index) => visibleItems[index]
|
|
2252
2835
|
}));
|
|
2253
|
-
return /* @__PURE__ */
|
|
2254
|
-
|
|
2836
|
+
return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement(
|
|
2837
|
+
import_noya_designsystem2.FileExplorerLayout,
|
|
2255
2838
|
{
|
|
2256
2839
|
title: title ?? rootMediaItemName,
|
|
2257
|
-
right: !readOnly && /* @__PURE__ */
|
|
2258
|
-
|
|
2840
|
+
right: !readOnly && /* @__PURE__ */ import_react5.default.createElement(
|
|
2841
|
+
import_noya_designsystem2.FileExplorerUploadButton,
|
|
2259
2842
|
{
|
|
2260
2843
|
showUploadButton,
|
|
2261
2844
|
onUpload: () => handleUpload(rootMediaItem.id),
|
|
@@ -2265,8 +2848,8 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2265
2848
|
),
|
|
2266
2849
|
className
|
|
2267
2850
|
},
|
|
2268
|
-
/* @__PURE__ */
|
|
2269
|
-
|
|
2851
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
2852
|
+
import_noya_designsystem2.FileExplorerCollection,
|
|
2270
2853
|
{
|
|
2271
2854
|
ref: collectionRef,
|
|
2272
2855
|
sortableId,
|
|
@@ -2309,7 +2892,7 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2309
2892
|
onRename,
|
|
2310
2893
|
renamable,
|
|
2311
2894
|
selectedIds,
|
|
2312
|
-
renderThumbnail: (props) => /* @__PURE__ */
|
|
2895
|
+
renderThumbnail: (props) => /* @__PURE__ */ import_react5.default.createElement(
|
|
2313
2896
|
MediaThumbnailInternal,
|
|
2314
2897
|
{
|
|
2315
2898
|
...props,
|
|
@@ -2322,9 +2905,9 @@ var MediaCollection = (0, import_react.memo)(
|
|
|
2322
2905
|
if (file.kind !== "asset") return null;
|
|
2323
2906
|
const asset = assets.find((a) => a.stableId === file.assetId) ?? assets.find((a) => a.id === file.assetId);
|
|
2324
2907
|
if (!asset) return null;
|
|
2325
|
-
return /* @__PURE__ */
|
|
2908
|
+
return /* @__PURE__ */ import_react5.default.createElement(import_noya_designsystem2.FileExplorerDetail, { selected, size }, (0, import_noya_designsystem2.formatByteSize)(asset.size));
|
|
2326
2909
|
},
|
|
2327
|
-
renderEmptyState: () => renderEmptyState?.() ?? /* @__PURE__ */
|
|
2910
|
+
renderEmptyState: () => renderEmptyState?.() ?? /* @__PURE__ */ import_react5.default.createElement(import_noya_designsystem2.FileExplorerEmptyState, null),
|
|
2328
2911
|
itemRoleDescription: "clickable file item",
|
|
2329
2912
|
getDropTargetParentIndex: (overIndex) => {
|
|
2330
2913
|
const item = visibleItems[overIndex];
|
|
@@ -2397,16 +2980,16 @@ function acceptsMediaItemDrop(parameters) {
|
|
|
2397
2980
|
}
|
|
2398
2981
|
|
|
2399
2982
|
// src/ResourceExplorer.tsx
|
|
2400
|
-
var
|
|
2401
|
-
var
|
|
2983
|
+
var import_noya_designsystem3 = require("@noya-app/noya-designsystem");
|
|
2984
|
+
var import_noya_icons3 = require("@noya-app/noya-icons");
|
|
2402
2985
|
var import_noya_multiplayer_react2 = require("@noya-app/noya-multiplayer-react");
|
|
2403
2986
|
var import_noya_schemas3 = require("@noya-app/noya-schemas");
|
|
2404
2987
|
var import_noya_utils4 = require("@noya-app/noya-utils");
|
|
2405
|
-
var
|
|
2406
|
-
var
|
|
2407
|
-
var
|
|
2988
|
+
var import_react_utils5 = require("@noya-app/react-utils");
|
|
2989
|
+
var import_browser_fs_access3 = require("browser-fs-access");
|
|
2990
|
+
var import_react6 = require("react");
|
|
2408
2991
|
var import_imfs6 = require("imfs");
|
|
2409
|
-
var
|
|
2992
|
+
var import_react7 = __toESM(require("react"));
|
|
2410
2993
|
|
|
2411
2994
|
// src/utils/contentType.ts
|
|
2412
2995
|
function getContentTypeFromFile(file) {
|
|
@@ -2487,13 +3070,8 @@ function getContentTypeFromExtension(extension) {
|
|
|
2487
3070
|
// src/utils/handleFileDrop.ts
|
|
2488
3071
|
var import_noya_schemas2 = require("@noya-app/noya-schemas");
|
|
2489
3072
|
var import_noya_utils3 = require("@noya-app/noya-utils");
|
|
3073
|
+
var import_react_utils4 = require("@noya-app/react-utils");
|
|
2490
3074
|
var import_imfs5 = require("imfs");
|
|
2491
|
-
function isDirectoryEntry(entry) {
|
|
2492
|
-
return entry.isDirectory;
|
|
2493
|
-
}
|
|
2494
|
-
function isFileEntry(entry) {
|
|
2495
|
-
return entry.isFile;
|
|
2496
|
-
}
|
|
2497
3075
|
async function handleDataTransfer({
|
|
2498
3076
|
accessibleByFileId,
|
|
2499
3077
|
dataTransfer,
|
|
@@ -2501,66 +3079,7 @@ async function handleDataTransfer({
|
|
|
2501
3079
|
resourceMap
|
|
2502
3080
|
}) {
|
|
2503
3081
|
try {
|
|
2504
|
-
const
|
|
2505
|
-
const supportsEntries = dataTransferItems.some(
|
|
2506
|
-
(item) => typeof item?.webkitGetAsEntry === "function"
|
|
2507
|
-
);
|
|
2508
|
-
const collectFromEntry = async (entry, basePath) => {
|
|
2509
|
-
if (!entry) return [];
|
|
2510
|
-
if (isFileEntry(entry)) {
|
|
2511
|
-
const file = await new Promise(
|
|
2512
|
-
(resolve) => entry.file((f) => resolve(f))
|
|
2513
|
-
);
|
|
2514
|
-
return [
|
|
2515
|
-
{
|
|
2516
|
-
file,
|
|
2517
|
-
relativePath: import_imfs5.path.join(basePath, file.name)
|
|
2518
|
-
}
|
|
2519
|
-
];
|
|
2520
|
-
}
|
|
2521
|
-
if (isDirectoryEntry(entry)) {
|
|
2522
|
-
const reader = entry.createReader();
|
|
2523
|
-
const readAll = async () => {
|
|
2524
|
-
const all = [];
|
|
2525
|
-
while (true) {
|
|
2526
|
-
const entries = await new Promise(
|
|
2527
|
-
(resolve) => reader.readEntries((ents) => resolve(ents))
|
|
2528
|
-
);
|
|
2529
|
-
if (!entries.length) break;
|
|
2530
|
-
all.push(...entries);
|
|
2531
|
-
}
|
|
2532
|
-
return all;
|
|
2533
|
-
};
|
|
2534
|
-
const children = await readAll();
|
|
2535
|
-
const results = await Promise.all(
|
|
2536
|
-
children.map(
|
|
2537
|
-
(child) => collectFromEntry(child, import_imfs5.path.join(basePath, entry.name))
|
|
2538
|
-
)
|
|
2539
|
-
);
|
|
2540
|
-
return results.flat();
|
|
2541
|
-
}
|
|
2542
|
-
return [];
|
|
2543
|
-
};
|
|
2544
|
-
let dropped = [];
|
|
2545
|
-
if (supportsEntries) {
|
|
2546
|
-
const topLevelEntries = dataTransferItems.flatMap((item) => {
|
|
2547
|
-
const entry = item.webkitGetAsEntry?.();
|
|
2548
|
-
if (!entry) return [];
|
|
2549
|
-
return [entry];
|
|
2550
|
-
});
|
|
2551
|
-
const nested = await Promise.all(
|
|
2552
|
-
topLevelEntries.map((entry) => collectFromEntry(entry, ""))
|
|
2553
|
-
);
|
|
2554
|
-
dropped = nested.flat();
|
|
2555
|
-
} else {
|
|
2556
|
-
const files = Array.from(dataTransfer.files);
|
|
2557
|
-
if (files.length === 0) return;
|
|
2558
|
-
dropped = files.map((file) => ({
|
|
2559
|
-
file,
|
|
2560
|
-
// Best effort: try webkitRelativePath; fall back to name
|
|
2561
|
-
relativePath: file.webkitRelativePath && file.webkitRelativePath.length > 0 ? file.webkitRelativePath : file.name
|
|
2562
|
-
}));
|
|
2563
|
-
}
|
|
3082
|
+
const dropped = await (0, import_react_utils4.collectDroppedFiles)(dataTransfer);
|
|
2564
3083
|
if (dropped.length === 0) return;
|
|
2565
3084
|
const folderRelativePaths = /* @__PURE__ */ new Set();
|
|
2566
3085
|
for (const { relativePath } of dropped) {
|
|
@@ -2617,7 +3136,7 @@ var gridThumbnailDimension = {
|
|
|
2617
3136
|
width: 800,
|
|
2618
3137
|
height: 800
|
|
2619
3138
|
};
|
|
2620
|
-
var ResourceThumbnail = (0,
|
|
3139
|
+
var ResourceThumbnail = (0, import_react_utils5.memoGeneric)(
|
|
2621
3140
|
({
|
|
2622
3141
|
item,
|
|
2623
3142
|
selected,
|
|
@@ -2642,8 +3161,8 @@ var ResourceThumbnail = (0, import_react_utils2.memoGeneric)(
|
|
|
2642
3161
|
contentType = contentTypeProp;
|
|
2643
3162
|
}
|
|
2644
3163
|
const fileName = pathProp ? import_imfs6.path.basename(pathProp) : void 0;
|
|
2645
|
-
return /* @__PURE__ */
|
|
2646
|
-
|
|
3164
|
+
return /* @__PURE__ */ import_react7.default.createElement(
|
|
3165
|
+
import_noya_designsystem3.MediaThumbnail,
|
|
2647
3166
|
{
|
|
2648
3167
|
contentType,
|
|
2649
3168
|
iconName: isRoot ? "HomeIcon" : isFolder ? "FolderIcon" : void 0,
|
|
@@ -2658,8 +3177,8 @@ var ResourceThumbnail = (0, import_react_utils2.memoGeneric)(
|
|
|
2658
3177
|
);
|
|
2659
3178
|
}
|
|
2660
3179
|
);
|
|
2661
|
-
var ResourceExplorer = (0,
|
|
2662
|
-
(0,
|
|
3180
|
+
var ResourceExplorer = (0, import_react6.memo)(
|
|
3181
|
+
(0, import_react6.forwardRef)(
|
|
2663
3182
|
function ResourceExplorer2({
|
|
2664
3183
|
parentFileId,
|
|
2665
3184
|
sortableId,
|
|
@@ -2698,44 +3217,44 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2698
3217
|
renderUser,
|
|
2699
3218
|
showFileSizes = true
|
|
2700
3219
|
}, ref) {
|
|
2701
|
-
const setMedia = (0,
|
|
3220
|
+
const setMedia = (0, import_react6.useCallback)(
|
|
2702
3221
|
(...args) => {
|
|
2703
3222
|
setMediaProp?.(...args);
|
|
2704
3223
|
},
|
|
2705
3224
|
[setMediaProp]
|
|
2706
3225
|
);
|
|
2707
|
-
const tree = (0,
|
|
2708
|
-
const [tempItem, setTempItem] = (0,
|
|
3226
|
+
const tree = (0, import_react6.useMemo)(() => (0, import_noya_schemas3.createResourceTree)(media), [media]);
|
|
3227
|
+
const [tempItem, setTempItem] = (0, import_react6.useState)(
|
|
2709
3228
|
void 0
|
|
2710
3229
|
);
|
|
2711
|
-
const mediaWithTempItem = (0,
|
|
3230
|
+
const mediaWithTempItem = (0, import_react6.useMemo)(
|
|
2712
3231
|
() => ({
|
|
2713
3232
|
...media,
|
|
2714
3233
|
...tempItem ? { [tempItem[0]]: tempItem[1] } : {}
|
|
2715
3234
|
}),
|
|
2716
3235
|
[media, tempItem]
|
|
2717
3236
|
);
|
|
2718
|
-
const treeWithTempItem = (0,
|
|
3237
|
+
const treeWithTempItem = (0, import_react6.useMemo)(
|
|
2719
3238
|
() => (0, import_noya_schemas3.createResourceTree)(mediaWithTempItem),
|
|
2720
3239
|
[mediaWithTempItem]
|
|
2721
3240
|
);
|
|
2722
|
-
const temp = (0,
|
|
3241
|
+
const temp = (0, import_react6.useMemo)(
|
|
2723
3242
|
() => ({
|
|
2724
3243
|
media: mediaWithTempItem,
|
|
2725
3244
|
tree: treeWithTempItem
|
|
2726
3245
|
}),
|
|
2727
3246
|
[mediaWithTempItem, treeWithTempItem]
|
|
2728
3247
|
);
|
|
2729
|
-
const [selectedIds, setSelectedIds] = (0,
|
|
3248
|
+
const [selectedIds, setSelectedIds] = (0, import_react_utils5.useControlledOrUncontrolled)({
|
|
2730
3249
|
defaultValue: [],
|
|
2731
3250
|
value: selectedIdsProp,
|
|
2732
3251
|
onChange: onSelectionChange
|
|
2733
3252
|
});
|
|
2734
3253
|
const assetManager = (0, import_noya_multiplayer_react2.useAssetManager)();
|
|
2735
3254
|
const assets = (0, import_noya_multiplayer_react2.useAssets)();
|
|
2736
|
-
const [expandedMap, setExpandedMap] = (0,
|
|
2737
|
-
const visibleItems = (0,
|
|
2738
|
-
() =>
|
|
3255
|
+
const [expandedMap, setExpandedMap] = (0, import_react6.useState)({});
|
|
3256
|
+
const visibleItems = (0, import_react6.useMemo)(
|
|
3257
|
+
() => getVisibleItems2({
|
|
2739
3258
|
expandedMap,
|
|
2740
3259
|
fileKindFilter,
|
|
2741
3260
|
rootItemId,
|
|
@@ -2752,12 +3271,12 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2752
3271
|
showRootItem
|
|
2753
3272
|
]
|
|
2754
3273
|
);
|
|
2755
|
-
const depthMap = (0,
|
|
3274
|
+
const depthMap = (0, import_react6.useMemo)(
|
|
2756
3275
|
() => getDepthMap(import_noya_schemas3.rootResource, treeWithTempItem, showAllDescendants),
|
|
2757
3276
|
[treeWithTempItem, showAllDescendants]
|
|
2758
3277
|
);
|
|
2759
|
-
const collectionRef = (0,
|
|
2760
|
-
const selectedResources = (0,
|
|
3278
|
+
const collectionRef = (0, import_react6.useRef)(null);
|
|
3279
|
+
const selectedResources = (0, import_react6.useMemo)(
|
|
2761
3280
|
() => treeWithTempItem.resourcesWithRoot.filter(
|
|
2762
3281
|
(item) => selectedIds.includes(item.id)
|
|
2763
3282
|
),
|
|
@@ -2778,12 +3297,12 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2778
3297
|
if (!itemPath || !firstSelectedPath) return false;
|
|
2779
3298
|
return itemPath.startsWith(import_imfs6.path.dirname(firstSelectedPath));
|
|
2780
3299
|
});
|
|
2781
|
-
(0,
|
|
3300
|
+
(0, import_react6.useEffect)(() => {
|
|
2782
3301
|
if (initialExpanded) {
|
|
2783
3302
|
setExpandedMap(initialExpanded);
|
|
2784
3303
|
}
|
|
2785
3304
|
}, [initialExpanded]);
|
|
2786
|
-
const getExpanded = (0,
|
|
3305
|
+
const getExpanded = (0, import_react6.useCallback)(
|
|
2787
3306
|
(item) => {
|
|
2788
3307
|
if (!expandable) return void 0;
|
|
2789
3308
|
if (item.type !== "directory") return void 0;
|
|
@@ -2792,8 +3311,8 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2792
3311
|
},
|
|
2793
3312
|
[expandedMap, expandable]
|
|
2794
3313
|
);
|
|
2795
|
-
const openConfirmationDialog = (0,
|
|
2796
|
-
const handleDelete = (0,
|
|
3314
|
+
const openConfirmationDialog = (0, import_noya_designsystem3.useOpenConfirmationDialog)();
|
|
3315
|
+
const handleDelete = (0, import_react6.useCallback)(
|
|
2797
3316
|
async (selectedIds2) => {
|
|
2798
3317
|
const ok = await openConfirmationDialog({
|
|
2799
3318
|
title: "Delete items",
|
|
@@ -2826,7 +3345,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2826
3345
|
openConfirmationDialog
|
|
2827
3346
|
]
|
|
2828
3347
|
);
|
|
2829
|
-
const onRename = (0,
|
|
3348
|
+
const onRename = (0, import_react6.useCallback)(
|
|
2830
3349
|
(selectedItem, newName) => {
|
|
2831
3350
|
if (!renamable) return;
|
|
2832
3351
|
const selectedItemPath = treeWithTempItem.idToPathMap.get(
|
|
@@ -2862,7 +3381,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2862
3381
|
treeWithTempItem.idToPathMap
|
|
2863
3382
|
]
|
|
2864
3383
|
);
|
|
2865
|
-
const handleAddFolder = (0,
|
|
3384
|
+
const handleAddFolder = (0, import_react6.useCallback)(
|
|
2866
3385
|
(currentFolderId) => {
|
|
2867
3386
|
const currentFolderPath = tree.idToPathMap.get(currentFolderId);
|
|
2868
3387
|
if (!currentFolderPath) return;
|
|
@@ -2883,7 +3402,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2883
3402
|
},
|
|
2884
3403
|
[parentFileId, tree]
|
|
2885
3404
|
);
|
|
2886
|
-
const handleMoveUpAFolder = (0,
|
|
3405
|
+
const handleMoveUpAFolder = (0, import_react6.useCallback)(
|
|
2887
3406
|
(selectedIds2) => {
|
|
2888
3407
|
const newMedia = moveUpAFolder({
|
|
2889
3408
|
tree,
|
|
@@ -2895,11 +3414,11 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2895
3414
|
},
|
|
2896
3415
|
[media, tree, setMedia]
|
|
2897
3416
|
);
|
|
2898
|
-
const [isUploading, setIsUploading] = (0,
|
|
2899
|
-
const handleUpload = (0,
|
|
3417
|
+
const [isUploading, setIsUploading] = (0, import_react6.useState)(false);
|
|
3418
|
+
const handleUpload = (0, import_react6.useCallback)(
|
|
2900
3419
|
async (selectedId) => {
|
|
2901
3420
|
try {
|
|
2902
|
-
const files = await (0,
|
|
3421
|
+
const files = await (0, import_browser_fs_access3.fileOpen)({ multiple: true });
|
|
2903
3422
|
if (!files || !Array.isArray(files) || files.length === 0) return;
|
|
2904
3423
|
const parentPath = tree.idToPathMap.get(selectedId);
|
|
2905
3424
|
if (!parentPath) return;
|
|
@@ -2944,18 +3463,18 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2944
3463
|
},
|
|
2945
3464
|
[tree, setMedia, media, onAssetsUploaded, parentFileId]
|
|
2946
3465
|
);
|
|
2947
|
-
const handleDownload = (0,
|
|
3466
|
+
const handleDownload = (0, import_react6.useCallback)(
|
|
2948
3467
|
async (selectedItems) => {
|
|
2949
3468
|
const downloadPromises = selectedItems.filter((item) => item.type === "asset").map(async (item) => {
|
|
2950
3469
|
const asset = assets.find((a) => a.stableId === item.assetId) ?? assets.find((a) => a.id === item.assetId);
|
|
2951
3470
|
if (!asset?.url) return;
|
|
2952
|
-
return (0,
|
|
3471
|
+
return (0, import_react_utils5.downloadUrl)(asset.url, tree.getNameForId(item.id));
|
|
2953
3472
|
});
|
|
2954
3473
|
await Promise.all(downloadPromises);
|
|
2955
3474
|
},
|
|
2956
3475
|
[assets, tree]
|
|
2957
3476
|
);
|
|
2958
|
-
const handlePreview = (0,
|
|
3477
|
+
const handlePreview = (0, import_react6.useCallback)(
|
|
2959
3478
|
async (selectedItems) => {
|
|
2960
3479
|
const previewPromises = selectedItems.filter((item) => item.type === "asset").map(async (item) => {
|
|
2961
3480
|
const asset = assets.find((a) => a.stableId === item.assetId) ?? assets.find((a) => a.id === item.assetId);
|
|
@@ -2966,10 +3485,10 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2966
3485
|
},
|
|
2967
3486
|
[assets]
|
|
2968
3487
|
);
|
|
2969
|
-
const handleReplace = (0,
|
|
3488
|
+
const handleReplace = (0, import_react6.useCallback)(
|
|
2970
3489
|
async (selectedItem) => {
|
|
2971
3490
|
try {
|
|
2972
|
-
const file = await (0,
|
|
3491
|
+
const file = await (0, import_browser_fs_access3.fileOpen)();
|
|
2973
3492
|
if (!file) return;
|
|
2974
3493
|
const created = await assetManager.create(file);
|
|
2975
3494
|
const assetStableId = created.id;
|
|
@@ -2995,13 +3514,13 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
2995
3514
|
},
|
|
2996
3515
|
[media, setMedia, assetManager, tree]
|
|
2997
3516
|
);
|
|
2998
|
-
const handleRename = (0,
|
|
3517
|
+
const handleRename = (0, import_react6.useCallback)(
|
|
2999
3518
|
(selectedItemId) => {
|
|
3000
3519
|
collectionRef.current?.editName(selectedItemId);
|
|
3001
3520
|
},
|
|
3002
3521
|
[collectionRef]
|
|
3003
3522
|
);
|
|
3004
|
-
const handleMoveMediaInsideFolder = (0,
|
|
3523
|
+
const handleMoveMediaInsideFolder = (0, import_react6.useCallback)(
|
|
3005
3524
|
(sourceItems, targetItem) => {
|
|
3006
3525
|
const newMedia = moveMediaInsideFolder({
|
|
3007
3526
|
sourceItemIds: sourceItems.map((item) => item.id),
|
|
@@ -3019,52 +3538,52 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3019
3538
|
},
|
|
3020
3539
|
[media, setMedia, tree]
|
|
3021
3540
|
);
|
|
3022
|
-
const assetContextMenuItems = (0,
|
|
3023
|
-
return (0,
|
|
3541
|
+
const assetContextMenuItems = (0, import_react6.useMemo)(() => {
|
|
3542
|
+
return (0, import_noya_designsystem3.createSectionedMenu)(
|
|
3024
3543
|
[
|
|
3025
3544
|
!rootSelected && singleItemSelected && {
|
|
3026
3545
|
title: "Rename",
|
|
3027
3546
|
value: "rename",
|
|
3028
|
-
icon: /* @__PURE__ */
|
|
3547
|
+
icon: /* @__PURE__ */ import_react7.default.createElement(import_noya_icons3.InputIcon, null)
|
|
3029
3548
|
},
|
|
3030
3549
|
onlySingleAssetSelected && {
|
|
3031
3550
|
title: "Replace",
|
|
3032
3551
|
value: "replace",
|
|
3033
|
-
icon: /* @__PURE__ */
|
|
3552
|
+
icon: /* @__PURE__ */ import_react7.default.createElement(import_noya_icons3.UpdateIcon, null)
|
|
3034
3553
|
},
|
|
3035
3554
|
!rootSelected && {
|
|
3036
3555
|
title: "Delete",
|
|
3037
3556
|
value: "delete",
|
|
3038
|
-
icon: /* @__PURE__ */
|
|
3557
|
+
icon: /* @__PURE__ */ import_react7.default.createElement(import_noya_icons3.TrashIcon, null)
|
|
3039
3558
|
}
|
|
3040
3559
|
],
|
|
3041
3560
|
[
|
|
3042
3561
|
onlySingleFolderSelected && {
|
|
3043
3562
|
title: "Upload Files",
|
|
3044
3563
|
value: "upload",
|
|
3045
|
-
icon: /* @__PURE__ */
|
|
3564
|
+
icon: /* @__PURE__ */ import_react7.default.createElement(import_noya_icons3.UploadIcon, null)
|
|
3046
3565
|
},
|
|
3047
3566
|
onlySingleFolderSelected && {
|
|
3048
3567
|
title: "Add Folder",
|
|
3049
3568
|
value: "addFolder",
|
|
3050
|
-
icon: /* @__PURE__ */
|
|
3569
|
+
icon: /* @__PURE__ */ import_react7.default.createElement(import_noya_icons3.FolderIcon, null)
|
|
3051
3570
|
},
|
|
3052
3571
|
onlyAssetsSelected && tree.resourcesWithRoot.length > 0 && {
|
|
3053
3572
|
title: "Download",
|
|
3054
3573
|
value: "download",
|
|
3055
|
-
icon: /* @__PURE__ */
|
|
3574
|
+
icon: /* @__PURE__ */ import_react7.default.createElement(import_noya_icons3.DownloadIcon, null)
|
|
3056
3575
|
},
|
|
3057
3576
|
onlySingleAssetSelected && {
|
|
3058
3577
|
title: "Preview",
|
|
3059
3578
|
value: "preview",
|
|
3060
|
-
icon: /* @__PURE__ */
|
|
3579
|
+
icon: /* @__PURE__ */ import_react7.default.createElement(import_noya_icons3.OpenInNewWindowIcon, null)
|
|
3061
3580
|
}
|
|
3062
3581
|
],
|
|
3063
3582
|
[
|
|
3064
3583
|
!rootSelected && sameParentSelected && {
|
|
3065
3584
|
title: "Move up a folder",
|
|
3066
3585
|
value: "move",
|
|
3067
|
-
icon: /* @__PURE__ */
|
|
3586
|
+
icon: /* @__PURE__ */ import_react7.default.createElement(import_noya_icons3.ResetIcon, null)
|
|
3068
3587
|
}
|
|
3069
3588
|
]
|
|
3070
3589
|
);
|
|
@@ -3077,7 +3596,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3077
3596
|
tree.resourcesWithRoot.length,
|
|
3078
3597
|
sameParentSelected
|
|
3079
3598
|
]);
|
|
3080
|
-
const handleMenuAction = (0,
|
|
3599
|
+
const handleMenuAction = (0, import_react6.useCallback)(
|
|
3081
3600
|
async (action, selectedItems) => {
|
|
3082
3601
|
if (selectedItems.length === 0) return;
|
|
3083
3602
|
switch (action) {
|
|
@@ -3119,7 +3638,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3119
3638
|
handleMoveUpAFolder
|
|
3120
3639
|
]
|
|
3121
3640
|
);
|
|
3122
|
-
const handleSetExpanded = (0,
|
|
3641
|
+
const handleSetExpanded = (0, import_react6.useCallback)(
|
|
3123
3642
|
(item, expanded) => {
|
|
3124
3643
|
setExpandedMap(
|
|
3125
3644
|
(prev) => updateExpandedMap({
|
|
@@ -3133,12 +3652,12 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3133
3652
|
},
|
|
3134
3653
|
[expandable, tree]
|
|
3135
3654
|
);
|
|
3136
|
-
const renderAction = (0,
|
|
3655
|
+
const renderAction = (0, import_react6.useMemo)(() => {
|
|
3137
3656
|
if (renderActionProp) return renderActionProp;
|
|
3138
3657
|
return ({
|
|
3139
3658
|
selected,
|
|
3140
3659
|
onOpenChange
|
|
3141
|
-
}) => /* @__PURE__ */
|
|
3660
|
+
}) => /* @__PURE__ */ import_react7.default.createElement(
|
|
3142
3661
|
"div",
|
|
3143
3662
|
{
|
|
3144
3663
|
style: {
|
|
@@ -3147,8 +3666,8 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3147
3666
|
justifyContent: "flex-end"
|
|
3148
3667
|
}
|
|
3149
3668
|
},
|
|
3150
|
-
/* @__PURE__ */
|
|
3151
|
-
|
|
3669
|
+
/* @__PURE__ */ import_react7.default.createElement(
|
|
3670
|
+
import_noya_designsystem3.ActionMenu,
|
|
3152
3671
|
{
|
|
3153
3672
|
menuItems: assetContextMenuItems,
|
|
3154
3673
|
onSelect: (action) => handleMenuAction(action, selectedResources),
|
|
@@ -3156,8 +3675,8 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3156
3675
|
onOpenChange,
|
|
3157
3676
|
variant: viewType === "grid" ? "normal" : "bare",
|
|
3158
3677
|
style: {
|
|
3159
|
-
backgroundColor: selected ?
|
|
3160
|
-
color: selected ?
|
|
3678
|
+
backgroundColor: selected ? import_noya_designsystem3.cssVars.colors.selectedListItemBackground : "transparent",
|
|
3679
|
+
color: selected ? import_noya_designsystem3.cssVars.colors.selectedListItemText : void 0
|
|
3161
3680
|
}
|
|
3162
3681
|
}
|
|
3163
3682
|
)
|
|
@@ -3169,7 +3688,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3169
3688
|
selectedResources,
|
|
3170
3689
|
viewType
|
|
3171
3690
|
]);
|
|
3172
|
-
(0,
|
|
3691
|
+
(0, import_react6.useImperativeHandle)(ref, () => ({
|
|
3173
3692
|
upload: (selectedId) => handleUpload(selectedId),
|
|
3174
3693
|
delete: handleDelete,
|
|
3175
3694
|
download: handleDownload,
|
|
@@ -3181,7 +3700,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3181
3700
|
moveMediaInsideFolder: handleMoveMediaInsideFolder,
|
|
3182
3701
|
getItemAtIndex: (index) => visibleItems[index]
|
|
3183
3702
|
}));
|
|
3184
|
-
const diffResources = (0,
|
|
3703
|
+
const diffResources = (0, import_react6.useMemo)(() => {
|
|
3185
3704
|
if (!publishedResources) return;
|
|
3186
3705
|
const diff = (0, import_noya_schemas3.diffResourceMaps)(publishedResources, media, "stableId");
|
|
3187
3706
|
return {
|
|
@@ -3196,9 +3715,9 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3196
3715
|
)
|
|
3197
3716
|
};
|
|
3198
3717
|
}, [media, publishedResources]);
|
|
3199
|
-
const keyExtractor = (0,
|
|
3200
|
-
const renderCollection = (virtualizedHeight) => /* @__PURE__ */
|
|
3201
|
-
|
|
3718
|
+
const keyExtractor = (0, import_react6.useCallback)((item) => item.id, []);
|
|
3719
|
+
const renderCollection = (virtualizedHeight) => /* @__PURE__ */ import_react7.default.createElement(
|
|
3720
|
+
import_noya_designsystem3.FileExplorerCollection,
|
|
3202
3721
|
{
|
|
3203
3722
|
ref: collectionRef,
|
|
3204
3723
|
sortableId,
|
|
@@ -3248,7 +3767,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3248
3767
|
itemClassName,
|
|
3249
3768
|
itemStyle,
|
|
3250
3769
|
virtualized: virtualizedHeight,
|
|
3251
|
-
renderThumbnail: (props) => /* @__PURE__ */
|
|
3770
|
+
renderThumbnail: (props) => /* @__PURE__ */ import_react7.default.createElement(
|
|
3252
3771
|
ResourceThumbnail,
|
|
3253
3772
|
{
|
|
3254
3773
|
...props,
|
|
@@ -3264,13 +3783,13 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3264
3783
|
resource: file,
|
|
3265
3784
|
diff: diffResources
|
|
3266
3785
|
});
|
|
3267
|
-
return /* @__PURE__ */
|
|
3786
|
+
return /* @__PURE__ */ import_react7.default.createElement(
|
|
3268
3787
|
"div",
|
|
3269
3788
|
{
|
|
3270
3789
|
style: { display: "flex", alignItems: "center", gap: "6px" }
|
|
3271
3790
|
},
|
|
3272
|
-
publishStatus && /* @__PURE__ */
|
|
3273
|
-
|
|
3791
|
+
publishStatus && /* @__PURE__ */ import_react7.default.createElement(
|
|
3792
|
+
import_noya_designsystem3.Chip,
|
|
3274
3793
|
{
|
|
3275
3794
|
colorScheme: publishStatus === "Modified" ? "info" : publishStatus === "Added" ? "secondary" : "primary"
|
|
3276
3795
|
},
|
|
@@ -3284,17 +3803,17 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3284
3803
|
if (file.type !== "asset") return null;
|
|
3285
3804
|
const asset = assets.find((a) => a.stableId === file.assetId) ?? assets.find((a) => a.id === file.assetId);
|
|
3286
3805
|
if (!asset) return null;
|
|
3287
|
-
return /* @__PURE__ */
|
|
3288
|
-
|
|
3806
|
+
return /* @__PURE__ */ import_react7.default.createElement(
|
|
3807
|
+
import_noya_designsystem3.FileExplorerDetail,
|
|
3289
3808
|
{
|
|
3290
3809
|
selected,
|
|
3291
3810
|
size,
|
|
3292
3811
|
style: { minWidth: "75px", textAlign: "right" }
|
|
3293
3812
|
},
|
|
3294
|
-
(0,
|
|
3813
|
+
(0, import_noya_designsystem3.formatByteSize)(asset.size)
|
|
3295
3814
|
);
|
|
3296
3815
|
},
|
|
3297
|
-
renderEmptyState: () => renderEmptyState?.() ?? /* @__PURE__ */
|
|
3816
|
+
renderEmptyState: () => renderEmptyState?.() ?? /* @__PURE__ */ import_react7.default.createElement(import_noya_designsystem3.FileExplorerEmptyState, null),
|
|
3298
3817
|
itemRoleDescription: "clickable file item",
|
|
3299
3818
|
getDropTargetParentIndex: (overIndex) => {
|
|
3300
3819
|
const item = visibleItems[overIndex];
|
|
@@ -3361,12 +3880,12 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3361
3880
|
}
|
|
3362
3881
|
}
|
|
3363
3882
|
);
|
|
3364
|
-
return /* @__PURE__ */
|
|
3365
|
-
|
|
3883
|
+
return /* @__PURE__ */ import_react7.default.createElement(
|
|
3884
|
+
import_noya_designsystem3.FileExplorerLayout,
|
|
3366
3885
|
{
|
|
3367
3886
|
title: title ?? import_noya_schemas3.rootResourceName,
|
|
3368
|
-
right: !readOnly && /* @__PURE__ */
|
|
3369
|
-
|
|
3887
|
+
right: !readOnly && /* @__PURE__ */ import_react7.default.createElement(
|
|
3888
|
+
import_noya_designsystem3.FileExplorerUploadButton,
|
|
3370
3889
|
{
|
|
3371
3890
|
showUploadButton,
|
|
3372
3891
|
onUpload: () => handleUpload(import_noya_schemas3.rootResource.id),
|
|
@@ -3376,7 +3895,7 @@ var ResourceExplorer = (0, import_react3.memo)(
|
|
|
3376
3895
|
),
|
|
3377
3896
|
className
|
|
3378
3897
|
},
|
|
3379
|
-
virtualized ? /* @__PURE__ */
|
|
3898
|
+
virtualized ? /* @__PURE__ */ import_react7.default.createElement(import_react_utils5.SingleDimensionAutoSizer, { dimension: "height" }, (height) => renderCollection(height)) : renderCollection(void 0)
|
|
3380
3899
|
);
|
|
3381
3900
|
}
|
|
3382
3901
|
)
|
|
@@ -3413,6 +3932,7 @@ function getPublishStatus({
|
|
|
3413
3932
|
}
|
|
3414
3933
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3415
3934
|
0 && (module.exports = {
|
|
3935
|
+
GitFileExplorer,
|
|
3416
3936
|
MediaCollection,
|
|
3417
3937
|
PLACEHOLDER_ITEM_NAME,
|
|
3418
3938
|
ResourceExplorer,
|