@muhgholy/next-drive 4.23.23 → 4.23.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/components/drive/dnd/context.d.ts.map +1 -1
- package/dist/client/components/drive/explorer.d.ts.map +1 -1
- package/dist/client/components/drive/file-grid.d.ts.map +1 -1
- package/dist/client/hooks/use-marquee.d.ts +14 -0
- package/dist/client/hooks/use-marquee.d.ts.map +1 -0
- package/dist/client/index.cjs +99 -10
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.js +99 -10
- package/dist/client/index.js.map +1 -1
- package/package.json +1 -1
package/dist/client/index.js
CHANGED
|
@@ -1530,9 +1530,16 @@ var DriveDndContext = createContext({
|
|
|
1530
1530
|
var useDriveDnd = () => useContext(DriveDndContext);
|
|
1531
1531
|
var DriveDndProvider = (props) => {
|
|
1532
1532
|
const { children } = props;
|
|
1533
|
-
const { items, setItems, sortBy, setSortBy, moveItem, callAPI, currentView } = useDrive();
|
|
1533
|
+
const { items, setItems, sortBy, setSortBy, moveItem, callAPI, currentView, selectedFileIds, setSelectedFiles } = useDrive();
|
|
1534
1534
|
const [dragOverFolderId, setDragOverFolderId] = useState(null);
|
|
1535
1535
|
const [draggingItemId, setDraggingItemId] = useState(null);
|
|
1536
|
+
const moveSelection = useCallback(async (activeId, targetFolderId) => {
|
|
1537
|
+
const ids = selectedFileIds.includes(activeId) && selectedFileIds.length > 1 ? selectedFileIds : [activeId];
|
|
1538
|
+
if (ids.length === 1) return moveItem(ids[0], targetFolderId);
|
|
1539
|
+
setItems((prev) => prev.filter((i) => !ids.includes(i.id)));
|
|
1540
|
+
setSelectedFiles([]);
|
|
1541
|
+
await callAPI("move", { method: "POST", body: JSON.stringify({ ids, targetFolderId }) });
|
|
1542
|
+
}, [selectedFileIds, moveItem, setItems, setSelectedFiles, callAPI]);
|
|
1536
1543
|
const sensors = useSensors(
|
|
1537
1544
|
useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),
|
|
1538
1545
|
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
|
|
@@ -1567,12 +1574,12 @@ var DriveDndProvider = (props) => {
|
|
|
1567
1574
|
if (overId.startsWith("path-")) {
|
|
1568
1575
|
const pathId = overId.slice(5);
|
|
1569
1576
|
const targetFolderId = pathId === "root" || pathId === "null" ? "root" : pathId;
|
|
1570
|
-
await
|
|
1577
|
+
await moveSelection(active.id, targetFolderId);
|
|
1571
1578
|
return;
|
|
1572
1579
|
}
|
|
1573
1580
|
const overItem = items.find((i) => i.id === over.id);
|
|
1574
1581
|
if (overItem?.information.type === "FOLDER") {
|
|
1575
|
-
await
|
|
1582
|
+
await moveSelection(active.id, over.id);
|
|
1576
1583
|
return;
|
|
1577
1584
|
}
|
|
1578
1585
|
const oldIndex = items.findIndex((i) => i.id === active.id);
|
|
@@ -1582,7 +1589,7 @@ var DriveDndProvider = (props) => {
|
|
|
1582
1589
|
setItems(reordered);
|
|
1583
1590
|
if (sortBy.field !== "order") setSortBy({ field: "order", order: 1 });
|
|
1584
1591
|
await callAPI("reorder", { method: "POST", body: JSON.stringify({ ids: reordered.map((i) => i.id) }) });
|
|
1585
|
-
}, [items, setItems, sortBy, setSortBy,
|
|
1592
|
+
}, [items, setItems, sortBy, setSortBy, moveSelection, callAPI]);
|
|
1586
1593
|
const enableDnd = currentView === "BROWSE";
|
|
1587
1594
|
return /* @__PURE__ */ jsx(DriveDndContext.Provider, { value: { dragOverFolderId, draggingItemId }, children: enableDnd ? /* @__PURE__ */ jsx(
|
|
1588
1595
|
DndContext,
|
|
@@ -1948,6 +1955,49 @@ var DriveItemRename = (props) => {
|
|
|
1948
1955
|
}
|
|
1949
1956
|
) });
|
|
1950
1957
|
};
|
|
1958
|
+
var useMarquee = (onSelectIds) => {
|
|
1959
|
+
const [box, setBox] = useState(null);
|
|
1960
|
+
const onMouseDown = (e) => {
|
|
1961
|
+
if (e.button !== 0 || e.target.closest("[data-marquee-id]")) return;
|
|
1962
|
+
const container = e.currentTarget;
|
|
1963
|
+
const start = { x: e.clientX, y: e.clientY };
|
|
1964
|
+
let moved = false;
|
|
1965
|
+
const handleMove = (ev) => {
|
|
1966
|
+
if (!moved && Math.abs(ev.clientX - start.x) < 4 && Math.abs(ev.clientY - start.y) < 4) return;
|
|
1967
|
+
moved = true;
|
|
1968
|
+
const left = Math.min(start.x, ev.clientX);
|
|
1969
|
+
const top = Math.min(start.y, ev.clientY);
|
|
1970
|
+
const right = Math.max(start.x, ev.clientX);
|
|
1971
|
+
const bottom = Math.max(start.y, ev.clientY);
|
|
1972
|
+
const cRect = container.getBoundingClientRect();
|
|
1973
|
+
setBox({
|
|
1974
|
+
left: left - cRect.left + container.scrollLeft,
|
|
1975
|
+
top: top - cRect.top + container.scrollTop,
|
|
1976
|
+
width: right - left,
|
|
1977
|
+
height: bottom - top
|
|
1978
|
+
});
|
|
1979
|
+
const ids = [];
|
|
1980
|
+
container.querySelectorAll("[data-marquee-id]").forEach((el) => {
|
|
1981
|
+
const r = el.getBoundingClientRect();
|
|
1982
|
+
if (r.left < right && r.right > left && r.top < bottom && r.bottom > top) ids.push(el.dataset.marqueeId);
|
|
1983
|
+
});
|
|
1984
|
+
onSelectIds(ids);
|
|
1985
|
+
};
|
|
1986
|
+
const handleUp = () => {
|
|
1987
|
+
window.removeEventListener("mousemove", handleMove);
|
|
1988
|
+
window.removeEventListener("mouseup", handleUp);
|
|
1989
|
+
if (!moved) onSelectIds([]);
|
|
1990
|
+
setBox(null);
|
|
1991
|
+
};
|
|
1992
|
+
window.addEventListener("mousemove", handleMove);
|
|
1993
|
+
window.addEventListener("mouseup", handleUp);
|
|
1994
|
+
};
|
|
1995
|
+
const overlay = box ? React3__default.createElement("div", {
|
|
1996
|
+
className: "nd:absolute nd:z-50 nd:rounded-sm nd:border nd:border-primary nd:bg-primary/10 nd:pointer-events-none",
|
|
1997
|
+
style: { left: box.left, top: box.top, width: box.width, height: box.height }
|
|
1998
|
+
}) : null;
|
|
1999
|
+
return { onMouseDown, overlay };
|
|
2000
|
+
};
|
|
1951
2001
|
var SortableItem = (props) => {
|
|
1952
2002
|
const { id, children, disabled, isDragOverTarget } = props;
|
|
1953
2003
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id, disabled });
|
|
@@ -1958,7 +2008,7 @@ var SortableItem = (props) => {
|
|
|
1958
2008
|
zIndex: isDragging ? 50 : "auto",
|
|
1959
2009
|
position: "relative"
|
|
1960
2010
|
};
|
|
1961
|
-
return /* @__PURE__ */ jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners, children });
|
|
2011
|
+
return /* @__PURE__ */ jsx("div", { ref: setNodeRef, "data-marquee-id": id, style, ...attributes, ...listeners, children });
|
|
1962
2012
|
};
|
|
1963
2013
|
var FileItem = (props) => {
|
|
1964
2014
|
const { item, isSelected, isDragOver, onSelect, onDoubleClick, onRename, onDelete, onRestore } = props;
|
|
@@ -2045,6 +2095,8 @@ var DriveFileGrid = (props) => {
|
|
|
2045
2095
|
sortBy,
|
|
2046
2096
|
selectedFileIds,
|
|
2047
2097
|
toggleSelected,
|
|
2098
|
+
setSelectedFiles,
|
|
2099
|
+
selectionMode,
|
|
2048
2100
|
navigateToFolder,
|
|
2049
2101
|
hasMore,
|
|
2050
2102
|
loadMore,
|
|
@@ -2056,6 +2108,19 @@ var DriveFileGrid = (props) => {
|
|
|
2056
2108
|
restoreItem
|
|
2057
2109
|
} = useDrive();
|
|
2058
2110
|
const { dragOverFolderId } = useDriveDnd();
|
|
2111
|
+
const { onMouseDown: marqueeMouseDown, overlay: marqueeOverlay } = useMarquee((ids) => {
|
|
2112
|
+
let files = items.filter((i) => ids.includes(i.id)).map((i) => ({
|
|
2113
|
+
id: i.id,
|
|
2114
|
+
file: {
|
|
2115
|
+
name: i.name,
|
|
2116
|
+
mime: i.information.type === "FILE" ? i.information.mime : "",
|
|
2117
|
+
size: i.information.type === "FILE" ? i.information.sizeInBytes : 0
|
|
2118
|
+
}
|
|
2119
|
+
}));
|
|
2120
|
+
if (selectionMode.type === "SINGLE") files = files.slice(0, 1);
|
|
2121
|
+
else if (selectionMode.maxFile) files = files.slice(0, selectionMode.maxFile);
|
|
2122
|
+
setSelectedFiles(files);
|
|
2123
|
+
});
|
|
2059
2124
|
const [dialogs, setDialogs] = React3__default.useState({ newFolder: false, rename: false, delete: false });
|
|
2060
2125
|
const [itemToDelete, setItemToDelete] = React3__default.useState(null);
|
|
2061
2126
|
const [itemToRename, setItemToRename] = React3__default.useState(null);
|
|
@@ -2178,7 +2243,8 @@ var DriveFileGrid = (props) => {
|
|
|
2178
2243
|
indicatorClassName: "nd:bg-primary"
|
|
2179
2244
|
}
|
|
2180
2245
|
) }),
|
|
2181
|
-
/* @__PURE__ */ jsxs("div", { className: cn("nd:flex-1 nd:overflow-y-auto nd:min-h-0 nd:p-2 nd:sm:p-3 nd:md:p-4", className), children: [
|
|
2246
|
+
/* @__PURE__ */ jsxs("div", { className: cn("nd:flex-1 nd:overflow-y-auto nd:min-h-0 nd:relative nd:p-2 nd:sm:p-3 nd:md:p-4", className), onMouseDown: marqueeMouseDown, children: [
|
|
2247
|
+
marqueeOverlay,
|
|
2182
2248
|
/* @__PURE__ */ jsx("div", { className: "nd:space-y-4 nd:sm:space-y-6", children: Object.entries(groupedItems).map(([groupName, groupItems]) => /* @__PURE__ */ jsxs("div", { children: [
|
|
2183
2249
|
groupBy !== "NONE" && /* @__PURE__ */ jsxs("h3", { className: "nd:text-xs nd:font-semibold nd:text-muted-foreground nd:uppercase nd:tracking-wide nd:mb-2 nd:sm:mb-3 nd:px-1", children: [
|
|
2184
2250
|
groupName,
|
|
@@ -3829,7 +3895,7 @@ var SortableItem2 = (props) => {
|
|
|
3829
3895
|
zIndex: isDragging ? 50 : "auto",
|
|
3830
3896
|
position: "relative"
|
|
3831
3897
|
};
|
|
3832
|
-
return /* @__PURE__ */ jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners, children });
|
|
3898
|
+
return /* @__PURE__ */ jsx("div", { ref: setNodeRef, "data-marquee-id": id, style, ...attributes, ...listeners, children });
|
|
3833
3899
|
};
|
|
3834
3900
|
var DriveExplorer = (props) => {
|
|
3835
3901
|
const { onItemClick, onItemDoubleClick, mimeFilter, className, selectableFolders = false } = props;
|
|
@@ -3846,6 +3912,8 @@ var DriveExplorer = (props) => {
|
|
|
3846
3912
|
setSortBy,
|
|
3847
3913
|
selectedFileIds,
|
|
3848
3914
|
toggleSelected,
|
|
3915
|
+
setSelectedFiles,
|
|
3916
|
+
selectionMode,
|
|
3849
3917
|
navigateToFolder,
|
|
3850
3918
|
hasMore,
|
|
3851
3919
|
loadMore,
|
|
@@ -3875,6 +3943,13 @@ var DriveExplorer = (props) => {
|
|
|
3875
3943
|
const handleDragStart = (event) => {
|
|
3876
3944
|
setDraggingItemId(event.active.id);
|
|
3877
3945
|
};
|
|
3946
|
+
const moveSelection = async (activeId, targetFolderId) => {
|
|
3947
|
+
const ids = selectedFileIds.includes(activeId) && selectedFileIds.length > 1 ? selectedFileIds : [activeId];
|
|
3948
|
+
if (ids.length === 1) return moveItem(ids[0], targetFolderId);
|
|
3949
|
+
setItems((prev) => prev.filter((i) => !ids.includes(i.id)));
|
|
3950
|
+
setSelectedFiles([]);
|
|
3951
|
+
await callAPI("move", { method: "POST", body: JSON.stringify({ ids, targetFolderId }) });
|
|
3952
|
+
};
|
|
3878
3953
|
const handleDragOver = (event) => {
|
|
3879
3954
|
const { over } = event;
|
|
3880
3955
|
if (!over) {
|
|
@@ -3898,13 +3973,13 @@ var DriveExplorer = (props) => {
|
|
|
3898
3973
|
const overId = over.id;
|
|
3899
3974
|
if (overId.startsWith("path-")) {
|
|
3900
3975
|
const targetFolderId = overId.replace("path-", "");
|
|
3901
|
-
await
|
|
3976
|
+
await moveSelection(active.id, targetFolderId === "root" ? "root" : targetFolderId);
|
|
3902
3977
|
return;
|
|
3903
3978
|
}
|
|
3904
3979
|
const overItem = items.find((i) => i.id === over.id);
|
|
3905
3980
|
const activeItem = items.find((i) => i.id === active.id);
|
|
3906
3981
|
if (overItem?.information.type === "FOLDER" && activeItem) {
|
|
3907
|
-
await
|
|
3982
|
+
await moveSelection(active.id, over.id);
|
|
3908
3983
|
return;
|
|
3909
3984
|
}
|
|
3910
3985
|
setItems((prevItems) => {
|
|
@@ -4008,6 +4083,19 @@ var DriveExplorer = (props) => {
|
|
|
4008
4083
|
} else onItemDoubleClick?.(item);
|
|
4009
4084
|
};
|
|
4010
4085
|
const enableDrag = currentView === "BROWSE";
|
|
4086
|
+
const { onMouseDown: marqueeMouseDown, overlay: marqueeOverlay } = useMarquee((ids) => {
|
|
4087
|
+
let files = items.filter((i) => ids.includes(i.id)).map((i) => ({
|
|
4088
|
+
id: i.id,
|
|
4089
|
+
file: {
|
|
4090
|
+
name: i.name,
|
|
4091
|
+
mime: i.information.type === "FILE" ? i.information.mime : "",
|
|
4092
|
+
size: i.information.type === "FILE" ? i.information.sizeInBytes : 0
|
|
4093
|
+
}
|
|
4094
|
+
}));
|
|
4095
|
+
if (selectionMode.type === "SINGLE") files = files.slice(0, 1);
|
|
4096
|
+
else if (selectionMode.maxFile) files = files.slice(0, selectionMode.maxFile);
|
|
4097
|
+
setSelectedFiles(files);
|
|
4098
|
+
});
|
|
4011
4099
|
const stateContent = (() => {
|
|
4012
4100
|
if (isLoading && items.length === 0) {
|
|
4013
4101
|
return /* @__PURE__ */ jsx("div", { className: "nd:flex nd:items-center nd:justify-center nd:py-12 nd:flex-1", children: /* @__PURE__ */ jsx(Loader2, { className: "nd:size-6 nd:animate-spin nd:text-muted-foreground" }) });
|
|
@@ -4038,7 +4126,8 @@ var DriveExplorer = (props) => {
|
|
|
4038
4126
|
] }),
|
|
4039
4127
|
/* @__PURE__ */ jsx("div", { className: "nd:lg:hidden nd:px-3 nd:py-2 nd:border-b nd:bg-background/95 nd:dark:bg-background/80 nd:backdrop-blur-sm", children: /* @__PURE__ */ jsx(DrivePathBar, {}) }),
|
|
4040
4128
|
stateContent || /* @__PURE__ */ jsxs(ContextMenu, { children: [
|
|
4041
|
-
/* @__PURE__ */ jsx(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: cn("nd:flex-1 nd:overflow-y-auto nd:min-h-0 nd:container nd:mx-auto nd:p-2 nd:sm:p-3 nd:md:p-4", className), children: [
|
|
4129
|
+
/* @__PURE__ */ jsx(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: cn("nd:flex-1 nd:overflow-y-auto nd:min-h-0 nd:relative nd:container nd:mx-auto nd:p-2 nd:sm:p-3 nd:md:p-4", className), onMouseDown: marqueeMouseDown, children: [
|
|
4130
|
+
marqueeOverlay,
|
|
4042
4131
|
/* @__PURE__ */ jsx("div", { className: "nd:space-y-4 nd:sm:space-y-6 nd:pb-8 nd:sm:pb-12", children: Object.entries(groupedItems).map(([groupName, groupItems]) => /* @__PURE__ */ jsxs("div", { className: "nd:space-y-3", children: [
|
|
4043
4132
|
groupBy !== "NONE" && /* @__PURE__ */ jsxs("h3", { className: "nd:text-sm nd:font-medium nd:text-muted-foreground nd:flex nd:items-center nd:gap-2", children: [
|
|
4044
4133
|
groupName,
|