@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.
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/drive/dnd/context.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAgBhF,KAAK,mBAAmB,GAAG;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAOF,eAAO,MAAM,WAAW,2BAAoC,CAAC;AAG7D,eAAO,MAAM,gBAAgB,GAAI,OAAO,QAAQ,CAAC;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAC,sBAuG9E,CAAC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/drive/dnd/context.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAgBhF,KAAK,mBAAmB,GAAG;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAOF,eAAO,MAAM,WAAW,2BAAoC,CAAC;AAG7D,eAAO,MAAM,gBAAgB,GAAI,OAAO,QAAQ,CAAC;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAC,sBAgH9E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../../../../src/client/components/drive/explorer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAqErD,eAAO,MAAM,aAAa,GAAI,OAAO,QAAQ,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC,sBA0eD,CAAC"}
1
+ {"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../../../../src/client/components/drive/explorer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAsErD,eAAO,MAAM,aAAa,GAAI,OAAO,QAAQ,CAAC;IACzC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC,sBAmgBD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-grid.d.ts","sourceRoot":"","sources":["../../../../src/client/components/drive/file-grid.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AA8KrD,eAAO,MAAM,aAAa,GAAI,OAAO,QAAQ,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;CACtD,CAAC,sBAsQD,CAAC"}
1
+ {"version":3,"file":"file-grid.d.ts","sourceRoot":"","sources":["../../../../src/client/components/drive/file-grid.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AA+KrD,eAAO,MAAM,aAAa,GAAI,OAAO,QAAQ,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;CACvD,CAAC,sBAsRD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ export declare const useMarquee: (onSelectIds: (ids: string[]) => void) => {
3
+ onMouseDown: (e: React.MouseEvent) => void;
4
+ overlay: React.DetailedReactHTMLElement<{
5
+ className: string;
6
+ style: {
7
+ left: number;
8
+ top: number;
9
+ width: number;
10
+ height: number;
11
+ };
12
+ }, HTMLElement> | null;
13
+ };
14
+ //# sourceMappingURL=use-marquee.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-marquee.d.ts","sourceRoot":"","sources":["../../../src/client/hooks/use-marquee.ts"],"names":[],"mappings":"AAGA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAKxC,eAAO,MAAM,UAAU,GAAI,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI;qBAGnC,KAAK,CAAC,UAAU;;;;;;;;;;CAkD3C,CAAC"}
@@ -1556,9 +1556,16 @@ var DriveDndContext = React3.createContext({
1556
1556
  var useDriveDnd = () => React3.useContext(DriveDndContext);
1557
1557
  var DriveDndProvider = (props) => {
1558
1558
  const { children } = props;
1559
- const { items, setItems, sortBy, setSortBy, moveItem, callAPI, currentView } = useDrive();
1559
+ const { items, setItems, sortBy, setSortBy, moveItem, callAPI, currentView, selectedFileIds, setSelectedFiles } = useDrive();
1560
1560
  const [dragOverFolderId, setDragOverFolderId] = React3.useState(null);
1561
1561
  const [draggingItemId, setDraggingItemId] = React3.useState(null);
1562
+ const moveSelection = React3.useCallback(async (activeId, targetFolderId) => {
1563
+ const ids = selectedFileIds.includes(activeId) && selectedFileIds.length > 1 ? selectedFileIds : [activeId];
1564
+ if (ids.length === 1) return moveItem(ids[0], targetFolderId);
1565
+ setItems((prev) => prev.filter((i) => !ids.includes(i.id)));
1566
+ setSelectedFiles([]);
1567
+ await callAPI("move", { method: "POST", body: JSON.stringify({ ids, targetFolderId }) });
1568
+ }, [selectedFileIds, moveItem, setItems, setSelectedFiles, callAPI]);
1562
1569
  const sensors = core.useSensors(
1563
1570
  core.useSensor(core.PointerSensor, { activationConstraint: { distance: 8 } }),
1564
1571
  core.useSensor(core.KeyboardSensor, { coordinateGetter: sortable.sortableKeyboardCoordinates })
@@ -1593,12 +1600,12 @@ var DriveDndProvider = (props) => {
1593
1600
  if (overId.startsWith("path-")) {
1594
1601
  const pathId = overId.slice(5);
1595
1602
  const targetFolderId = pathId === "root" || pathId === "null" ? "root" : pathId;
1596
- await moveItem(active.id, targetFolderId);
1603
+ await moveSelection(active.id, targetFolderId);
1597
1604
  return;
1598
1605
  }
1599
1606
  const overItem = items.find((i) => i.id === over.id);
1600
1607
  if (overItem?.information.type === "FOLDER") {
1601
- await moveItem(active.id, over.id);
1608
+ await moveSelection(active.id, over.id);
1602
1609
  return;
1603
1610
  }
1604
1611
  const oldIndex = items.findIndex((i) => i.id === active.id);
@@ -1608,7 +1615,7 @@ var DriveDndProvider = (props) => {
1608
1615
  setItems(reordered);
1609
1616
  if (sortBy.field !== "order") setSortBy({ field: "order", order: 1 });
1610
1617
  await callAPI("reorder", { method: "POST", body: JSON.stringify({ ids: reordered.map((i) => i.id) }) });
1611
- }, [items, setItems, sortBy, setSortBy, moveItem, callAPI]);
1618
+ }, [items, setItems, sortBy, setSortBy, moveSelection, callAPI]);
1612
1619
  const enableDnd = currentView === "BROWSE";
1613
1620
  return /* @__PURE__ */ jsxRuntime.jsx(DriveDndContext.Provider, { value: { dragOverFolderId, draggingItemId }, children: enableDnd ? /* @__PURE__ */ jsxRuntime.jsx(
1614
1621
  core.DndContext,
@@ -1974,6 +1981,49 @@ var DriveItemRename = (props) => {
1974
1981
  }
1975
1982
  ) });
1976
1983
  };
1984
+ var useMarquee = (onSelectIds) => {
1985
+ const [box, setBox] = React3.useState(null);
1986
+ const onMouseDown = (e) => {
1987
+ if (e.button !== 0 || e.target.closest("[data-marquee-id]")) return;
1988
+ const container = e.currentTarget;
1989
+ const start = { x: e.clientX, y: e.clientY };
1990
+ let moved = false;
1991
+ const handleMove = (ev) => {
1992
+ if (!moved && Math.abs(ev.clientX - start.x) < 4 && Math.abs(ev.clientY - start.y) < 4) return;
1993
+ moved = true;
1994
+ const left = Math.min(start.x, ev.clientX);
1995
+ const top = Math.min(start.y, ev.clientY);
1996
+ const right = Math.max(start.x, ev.clientX);
1997
+ const bottom = Math.max(start.y, ev.clientY);
1998
+ const cRect = container.getBoundingClientRect();
1999
+ setBox({
2000
+ left: left - cRect.left + container.scrollLeft,
2001
+ top: top - cRect.top + container.scrollTop,
2002
+ width: right - left,
2003
+ height: bottom - top
2004
+ });
2005
+ const ids = [];
2006
+ container.querySelectorAll("[data-marquee-id]").forEach((el) => {
2007
+ const r = el.getBoundingClientRect();
2008
+ if (r.left < right && r.right > left && r.top < bottom && r.bottom > top) ids.push(el.dataset.marqueeId);
2009
+ });
2010
+ onSelectIds(ids);
2011
+ };
2012
+ const handleUp = () => {
2013
+ window.removeEventListener("mousemove", handleMove);
2014
+ window.removeEventListener("mouseup", handleUp);
2015
+ if (!moved) onSelectIds([]);
2016
+ setBox(null);
2017
+ };
2018
+ window.addEventListener("mousemove", handleMove);
2019
+ window.addEventListener("mouseup", handleUp);
2020
+ };
2021
+ const overlay = box ? React3__namespace.default.createElement("div", {
2022
+ className: "nd:absolute nd:z-50 nd:rounded-sm nd:border nd:border-primary nd:bg-primary/10 nd:pointer-events-none",
2023
+ style: { left: box.left, top: box.top, width: box.width, height: box.height }
2024
+ }) : null;
2025
+ return { onMouseDown, overlay };
2026
+ };
1977
2027
  var SortableItem = (props) => {
1978
2028
  const { id, children, disabled, isDragOverTarget } = props;
1979
2029
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortable.useSortable({ id, disabled });
@@ -1984,7 +2034,7 @@ var SortableItem = (props) => {
1984
2034
  zIndex: isDragging ? 50 : "auto",
1985
2035
  position: "relative"
1986
2036
  };
1987
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners, children });
2037
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, "data-marquee-id": id, style, ...attributes, ...listeners, children });
1988
2038
  };
1989
2039
  var FileItem = (props) => {
1990
2040
  const { item, isSelected, isDragOver, onSelect, onDoubleClick, onRename, onDelete, onRestore } = props;
@@ -2071,6 +2121,8 @@ var DriveFileGrid = (props) => {
2071
2121
  sortBy,
2072
2122
  selectedFileIds,
2073
2123
  toggleSelected,
2124
+ setSelectedFiles,
2125
+ selectionMode,
2074
2126
  navigateToFolder,
2075
2127
  hasMore,
2076
2128
  loadMore,
@@ -2082,6 +2134,19 @@ var DriveFileGrid = (props) => {
2082
2134
  restoreItem
2083
2135
  } = useDrive();
2084
2136
  const { dragOverFolderId } = useDriveDnd();
2137
+ const { onMouseDown: marqueeMouseDown, overlay: marqueeOverlay } = useMarquee((ids) => {
2138
+ let files = items.filter((i) => ids.includes(i.id)).map((i) => ({
2139
+ id: i.id,
2140
+ file: {
2141
+ name: i.name,
2142
+ mime: i.information.type === "FILE" ? i.information.mime : "",
2143
+ size: i.information.type === "FILE" ? i.information.sizeInBytes : 0
2144
+ }
2145
+ }));
2146
+ if (selectionMode.type === "SINGLE") files = files.slice(0, 1);
2147
+ else if (selectionMode.maxFile) files = files.slice(0, selectionMode.maxFile);
2148
+ setSelectedFiles(files);
2149
+ });
2085
2150
  const [dialogs, setDialogs] = React3__namespace.default.useState({ newFolder: false, rename: false, delete: false });
2086
2151
  const [itemToDelete, setItemToDelete] = React3__namespace.default.useState(null);
2087
2152
  const [itemToRename, setItemToRename] = React3__namespace.default.useState(null);
@@ -2204,7 +2269,8 @@ var DriveFileGrid = (props) => {
2204
2269
  indicatorClassName: "nd:bg-primary"
2205
2270
  }
2206
2271
  ) }),
2207
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkHQTC3554_cjs.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: [
2272
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkHQTC3554_cjs.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: [
2273
+ marqueeOverlay,
2208
2274
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nd:space-y-4 nd:sm:space-y-6", children: Object.entries(groupedItems).map(([groupName, groupItems]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2209
2275
  groupBy !== "NONE" && /* @__PURE__ */ jsxRuntime.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: [
2210
2276
  groupName,
@@ -3855,7 +3921,7 @@ var SortableItem2 = (props) => {
3855
3921
  zIndex: isDragging ? 50 : "auto",
3856
3922
  position: "relative"
3857
3923
  };
3858
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners, children });
3924
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, "data-marquee-id": id, style, ...attributes, ...listeners, children });
3859
3925
  };
3860
3926
  var DriveExplorer = (props) => {
3861
3927
  const { onItemClick, onItemDoubleClick, mimeFilter, className, selectableFolders = false } = props;
@@ -3872,6 +3938,8 @@ var DriveExplorer = (props) => {
3872
3938
  setSortBy,
3873
3939
  selectedFileIds,
3874
3940
  toggleSelected,
3941
+ setSelectedFiles,
3942
+ selectionMode,
3875
3943
  navigateToFolder,
3876
3944
  hasMore,
3877
3945
  loadMore,
@@ -3901,6 +3969,13 @@ var DriveExplorer = (props) => {
3901
3969
  const handleDragStart = (event) => {
3902
3970
  setDraggingItemId(event.active.id);
3903
3971
  };
3972
+ const moveSelection = async (activeId, targetFolderId) => {
3973
+ const ids = selectedFileIds.includes(activeId) && selectedFileIds.length > 1 ? selectedFileIds : [activeId];
3974
+ if (ids.length === 1) return moveItem(ids[0], targetFolderId);
3975
+ setItems((prev) => prev.filter((i) => !ids.includes(i.id)));
3976
+ setSelectedFiles([]);
3977
+ await callAPI("move", { method: "POST", body: JSON.stringify({ ids, targetFolderId }) });
3978
+ };
3904
3979
  const handleDragOver = (event) => {
3905
3980
  const { over } = event;
3906
3981
  if (!over) {
@@ -3924,13 +3999,13 @@ var DriveExplorer = (props) => {
3924
3999
  const overId = over.id;
3925
4000
  if (overId.startsWith("path-")) {
3926
4001
  const targetFolderId = overId.replace("path-", "");
3927
- await moveItem(active.id, targetFolderId === "root" ? "root" : targetFolderId);
4002
+ await moveSelection(active.id, targetFolderId === "root" ? "root" : targetFolderId);
3928
4003
  return;
3929
4004
  }
3930
4005
  const overItem = items.find((i) => i.id === over.id);
3931
4006
  const activeItem = items.find((i) => i.id === active.id);
3932
4007
  if (overItem?.information.type === "FOLDER" && activeItem) {
3933
- await moveItem(active.id, over.id);
4008
+ await moveSelection(active.id, over.id);
3934
4009
  return;
3935
4010
  }
3936
4011
  setItems((prevItems) => {
@@ -4034,6 +4109,19 @@ var DriveExplorer = (props) => {
4034
4109
  } else onItemDoubleClick?.(item);
4035
4110
  };
4036
4111
  const enableDrag = currentView === "BROWSE";
4112
+ const { onMouseDown: marqueeMouseDown, overlay: marqueeOverlay } = useMarquee((ids) => {
4113
+ let files = items.filter((i) => ids.includes(i.id)).map((i) => ({
4114
+ id: i.id,
4115
+ file: {
4116
+ name: i.name,
4117
+ mime: i.information.type === "FILE" ? i.information.mime : "",
4118
+ size: i.information.type === "FILE" ? i.information.sizeInBytes : 0
4119
+ }
4120
+ }));
4121
+ if (selectionMode.type === "SINGLE") files = files.slice(0, 1);
4122
+ else if (selectionMode.maxFile) files = files.slice(0, selectionMode.maxFile);
4123
+ setSelectedFiles(files);
4124
+ });
4037
4125
  const stateContent = (() => {
4038
4126
  if (isLoading && items.length === 0) {
4039
4127
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nd:flex nd:items-center nd:justify-center nd:py-12 nd:flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "nd:size-6 nd:animate-spin nd:text-muted-foreground" }) });
@@ -4064,7 +4152,8 @@ var DriveExplorer = (props) => {
4064
4152
  ] }),
4065
4153
  /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(DrivePathBar, {}) }),
4066
4154
  stateContent || /* @__PURE__ */ jsxRuntime.jsxs(ContextMenu, { children: [
4067
- /* @__PURE__ */ jsxRuntime.jsx(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkHQTC3554_cjs.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: [
4155
+ /* @__PURE__ */ jsxRuntime.jsx(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkHQTC3554_cjs.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: [
4156
+ marqueeOverlay,
4068
4157
  /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("div", { className: "nd:space-y-3", children: [
4069
4158
  groupBy !== "NONE" && /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "nd:text-sm nd:font-medium nd:text-muted-foreground nd:flex nd:items-center nd:gap-2", children: [
4070
4159
  groupName,