@muhgholy/next-drive 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +222 -346
- package/dist/{chunk-5C6YUPCM.js → chunk-F5SLCUJ5.js} +26 -8
- package/dist/chunk-F5SLCUJ5.js.map +1 -0
- package/dist/client/components/dialog.d.ts.map +1 -1
- package/dist/client/components/drive/dnd-provider.d.ts +2 -2
- package/dist/client/components/drive/dnd-provider.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/components/drive/header.d.ts +4 -1
- package/dist/client/components/drive/header.d.ts.map +1 -1
- package/dist/client/components/drive/path-bar.d.ts +3 -1
- package/dist/client/components/drive/path-bar.d.ts.map +1 -1
- package/dist/client/components/drive/sidebar.d.ts +3 -1
- package/dist/client/components/drive/sidebar.d.ts.map +1 -1
- package/dist/client/components/drive/storage/indicator.d.ts.map +1 -1
- package/dist/client/components/drive/upload.d.ts.map +1 -1
- package/dist/client/components/ui/progress.d.ts +2 -1
- package/dist/client/components/ui/progress.d.ts.map +1 -1
- package/dist/client/components/ui/sheet.d.ts.map +1 -1
- package/dist/client/context.d.ts +4 -0
- package/dist/client/context.d.ts.map +1 -1
- package/dist/client/file-chooser.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +487 -281
- package/dist/client/index.js.map +1 -1
- package/dist/client/styles.css +57 -40
- package/dist/server/express.js +2 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/providers/google.d.ts.map +1 -1
- package/package.json +5 -1
- package/dist/chunk-5C6YUPCM.js.map +0 -1
- package/dist/client/index.css +0 -48
- package/dist/client/index.css.map +0 -1
package/dist/client/index.js
CHANGED
|
@@ -7,15 +7,15 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
7
7
|
import { Slot } from '@radix-ui/react-slot';
|
|
8
8
|
import { cva } from 'class-variance-authority';
|
|
9
9
|
import * as SheetPrimitive from '@radix-ui/react-dialog';
|
|
10
|
-
import { X, ChevronRight, Check, Circle, Loader2, Folder, FolderPlus, Menu, RotateCcw, Trash2, Group, ArrowUpDown, Calendar, ArrowDownAZ, ArrowUpAZ, ArrowDown01, ArrowUp01, LayoutGrid, List, Upload, Cloud, AlertCircle, Pencil,
|
|
10
|
+
import { X, ChevronRight, Check, Circle, Loader2, Folder, FolderPlus, Menu, RotateCcw, Trash2, Group, ArrowUpDown, Calendar, ArrowDownAZ, ArrowUpAZ, ArrowDown01, ArrowUp01, LayoutGrid, List, RefreshCw, Upload, CheckCircle2, Cloud, AlertCircle, Pencil, HardDrive, Database, ChevronsUpDown, Plus, Settings2, Trash, FolderOpen, Clock } from 'lucide-react';
|
|
11
11
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
12
12
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
13
13
|
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, pointerWithin, closestCenter, useDroppable } from '@dnd-kit/core';
|
|
14
14
|
import { sortableKeyboardCoordinates, arrayMove, SortableContext, rectSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
15
|
+
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
15
16
|
import { startOfWeek, subWeeks, isToday, isYesterday, isAfter } from 'date-fns';
|
|
16
17
|
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
|
|
17
18
|
import { CSS } from '@dnd-kit/utilities';
|
|
18
|
-
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
19
19
|
|
|
20
20
|
var DriveContext = createContext(null);
|
|
21
21
|
var DriveProvider = (props) => {
|
|
@@ -34,6 +34,7 @@ var DriveProvider = (props) => {
|
|
|
34
34
|
const [path, setPath] = useState([{ id: null, name: "Home" }]);
|
|
35
35
|
const [accounts, setAccounts] = useState([]);
|
|
36
36
|
const [activeAccountId, setActiveAccountIdState] = useState(initialActiveAccountId);
|
|
37
|
+
const [availableProviders, setAvailableProviders] = useState({ google: false });
|
|
37
38
|
const [quota, setQuota] = useState(null);
|
|
38
39
|
const [viewMode, setViewMode] = useState(() => {
|
|
39
40
|
if (typeof window !== "undefined") return window.innerWidth < 768 ? "LIST" : "GRID";
|
|
@@ -105,6 +106,8 @@ var DriveProvider = (props) => {
|
|
|
105
106
|
const refreshAccounts = useCallback(async () => {
|
|
106
107
|
const res = await callAPI("listAccounts");
|
|
107
108
|
if (res.status === 200 && res.data) setAccounts(res.data.accounts);
|
|
109
|
+
const infoRes = await callAPI("information");
|
|
110
|
+
if (infoRes.status === 200 && infoRes.data) setAvailableProviders(infoRes.data.providers);
|
|
108
111
|
}, [callAPI]);
|
|
109
112
|
const refreshQuota = useCallback(async () => {
|
|
110
113
|
const res = await callAPI("quota");
|
|
@@ -123,6 +126,7 @@ var DriveProvider = (props) => {
|
|
|
123
126
|
setCurrentView("BROWSE");
|
|
124
127
|
setSearchQuery("");
|
|
125
128
|
setSelectedFileIds([]);
|
|
129
|
+
setIsLoading(true);
|
|
126
130
|
if (!item) {
|
|
127
131
|
setCurrentFolderId(null);
|
|
128
132
|
setPath([{ id: null, name: "Home" }]);
|
|
@@ -139,6 +143,7 @@ var DriveProvider = (props) => {
|
|
|
139
143
|
setCurrentView("BROWSE");
|
|
140
144
|
setSearchQuery("");
|
|
141
145
|
setSelectedFileIds([]);
|
|
146
|
+
setIsLoading(true);
|
|
142
147
|
const newPath = path.slice(0, -1);
|
|
143
148
|
setPath(newPath);
|
|
144
149
|
setCurrentFolderId(newPath[newPath.length - 1]?.id || null);
|
|
@@ -225,11 +230,13 @@ var DriveProvider = (props) => {
|
|
|
225
230
|
setItems,
|
|
226
231
|
isLoading,
|
|
227
232
|
error,
|
|
233
|
+
fetchItems,
|
|
228
234
|
// Accounts
|
|
229
235
|
accounts,
|
|
230
236
|
activeAccountId,
|
|
231
237
|
setActiveAccountId,
|
|
232
238
|
refreshAccounts,
|
|
239
|
+
availableProviders,
|
|
233
240
|
// Storage
|
|
234
241
|
quota,
|
|
235
242
|
refreshQuota,
|
|
@@ -1029,6 +1036,7 @@ var DialogConfirmation = (props) => {
|
|
|
1029
1036
|
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(
|
|
1030
1037
|
DialogContent,
|
|
1031
1038
|
{
|
|
1039
|
+
showCloseButton: false,
|
|
1032
1040
|
onInteractOutside: (e) => {
|
|
1033
1041
|
if (disableEscapeKeyDown) {
|
|
1034
1042
|
e.preventDefault();
|
|
@@ -1082,7 +1090,8 @@ var DriveDndContext = createContext({
|
|
|
1082
1090
|
draggingItemId: null
|
|
1083
1091
|
});
|
|
1084
1092
|
var useDriveDnd = () => useContext(DriveDndContext);
|
|
1085
|
-
var DriveDndProvider = (
|
|
1093
|
+
var DriveDndProvider = (props) => {
|
|
1094
|
+
const { children } = props;
|
|
1086
1095
|
const { items, setItems, sortBy, setSortBy, moveItem, callAPI, currentView } = useDrive();
|
|
1087
1096
|
const [dragOverFolderId, setDragOverFolderId] = useState(null);
|
|
1088
1097
|
const [draggingItemId, setDraggingItemId] = useState(null);
|
|
@@ -1149,6 +1158,39 @@ var DriveDndProvider = ({ children }) => {
|
|
|
1149
1158
|
}
|
|
1150
1159
|
) : children });
|
|
1151
1160
|
};
|
|
1161
|
+
function Progress({
|
|
1162
|
+
className,
|
|
1163
|
+
value,
|
|
1164
|
+
indicatorClassName,
|
|
1165
|
+
indeterminate = false,
|
|
1166
|
+
...props
|
|
1167
|
+
}) {
|
|
1168
|
+
const isIndeterminate = indeterminate || value === void 0;
|
|
1169
|
+
return /* @__PURE__ */ jsx(
|
|
1170
|
+
ProgressPrimitive.Root,
|
|
1171
|
+
{
|
|
1172
|
+
"data-slot": "progress",
|
|
1173
|
+
className: cn(
|
|
1174
|
+
"bg-primary/20 relative h-2 w-full overflow-hidden rounded-full",
|
|
1175
|
+
className
|
|
1176
|
+
),
|
|
1177
|
+
...props,
|
|
1178
|
+
children: /* @__PURE__ */ jsx(
|
|
1179
|
+
ProgressPrimitive.Indicator,
|
|
1180
|
+
{
|
|
1181
|
+
"data-slot": "progress-indicator",
|
|
1182
|
+
className: cn(
|
|
1183
|
+
"bg-primary h-full flex-1 transition-all",
|
|
1184
|
+
isIndeterminate && "w-1/3 animate-indeterminate",
|
|
1185
|
+
!isIndeterminate && "w-full",
|
|
1186
|
+
indicatorClassName
|
|
1187
|
+
),
|
|
1188
|
+
style: isIndeterminate ? void 0 : { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
1189
|
+
}
|
|
1190
|
+
)
|
|
1191
|
+
}
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1152
1194
|
var ContextMenu = ContextMenuPrimitive.Root;
|
|
1153
1195
|
var ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
1154
1196
|
var ContextMenuSubTrigger = React3.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
@@ -1260,7 +1302,8 @@ var ContextMenuSeparator = React3.forwardRef(({ className, ...props }, ref) => /
|
|
|
1260
1302
|
}
|
|
1261
1303
|
));
|
|
1262
1304
|
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
|
|
1263
|
-
var SortableItem = (
|
|
1305
|
+
var SortableItem = (props) => {
|
|
1306
|
+
const { id, children, disabled, isDragOverTarget } = props;
|
|
1264
1307
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id, disabled });
|
|
1265
1308
|
const style = {
|
|
1266
1309
|
transform: isDragOverTarget ? void 0 : CSS.Transform.toString(transform),
|
|
@@ -1271,7 +1314,8 @@ var SortableItem = ({ id, children, disabled, isDragOverTarget }) => {
|
|
|
1271
1314
|
};
|
|
1272
1315
|
return /* @__PURE__ */ jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners, children });
|
|
1273
1316
|
};
|
|
1274
|
-
var FileItem = (
|
|
1317
|
+
var FileItem = (props) => {
|
|
1318
|
+
const { item, isSelected, isDragOver, onSelect, onDoubleClick, onRename, onDelete, onRestore } = props;
|
|
1275
1319
|
const { apiEndpoint, viewMode, currentView } = useDrive();
|
|
1276
1320
|
const isFolder = item.information.type === "FOLDER";
|
|
1277
1321
|
const tokenParam = item.token ? `&token=${item.token}` : "";
|
|
@@ -1460,34 +1504,36 @@ var DriveFileGrid = (props) => {
|
|
|
1460
1504
|
};
|
|
1461
1505
|
const enableDrag = currentView === "BROWSE";
|
|
1462
1506
|
if (isLoading && items.length === 0) {
|
|
1463
|
-
return /* @__PURE__ */
|
|
1507
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex-1 flex flex-col", className), children: [
|
|
1508
|
+
/* @__PURE__ */ jsx("div", { className: "h-1 w-full shrink-0", children: /* @__PURE__ */ jsx(
|
|
1509
|
+
Progress,
|
|
1510
|
+
{
|
|
1511
|
+
indeterminate: true,
|
|
1512
|
+
className: "h-full rounded-none bg-primary/10",
|
|
1513
|
+
indicatorClassName: "bg-primary"
|
|
1514
|
+
}
|
|
1515
|
+
) }),
|
|
1516
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsx(Loader2, { className: "size-8 animate-spin text-muted-foreground" }) })
|
|
1517
|
+
] });
|
|
1464
1518
|
}
|
|
1465
1519
|
if (error) {
|
|
1466
|
-
return /* @__PURE__ */ jsx("div", { className: cn("flex-1 flex items-center justify-center p-8", className), children: /* @__PURE__ */ jsx("
|
|
1520
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex-1 flex items-center justify-center p-8", className), children: /* @__PURE__ */ jsx("p", { className: "text-destructive font-medium text-center", children: error }) });
|
|
1467
1521
|
}
|
|
1468
1522
|
if (processedItems.length === 0) {
|
|
1469
|
-
return /* @__PURE__ */ jsxs(
|
|
1470
|
-
/* @__PURE__ */
|
|
1471
|
-
|
|
1472
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-muted-foreground", children: currentView === "SEARCH" ? "No files match your search" : currentView === "TRASH" ? "Trash is empty" : "This folder is empty" })
|
|
1473
|
-
] }),
|
|
1474
|
-
/* @__PURE__ */ jsx(
|
|
1475
|
-
DialogConfirmation,
|
|
1476
|
-
{
|
|
1477
|
-
open: dialogs.newFolder,
|
|
1478
|
-
onClose: () => setDialogs((prev) => ({ ...prev, newFolder: false })),
|
|
1479
|
-
title: "Create New Folder",
|
|
1480
|
-
description: "Enter a name for the new folder",
|
|
1481
|
-
inputs: [{ type: "INPUT", id: "name", name: "Folder name", required: true }],
|
|
1482
|
-
onConfirm: async (inputs) => {
|
|
1483
|
-
await createFolder(inputs.name);
|
|
1484
|
-
return [true];
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
)
|
|
1523
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex-1 flex flex-col items-center justify-center p-8 text-center", className), children: [
|
|
1524
|
+
/* @__PURE__ */ jsx("div", { className: "size-16 rounded-2xl bg-muted/50 dark:bg-muted/30 flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx(Folder, { className: "size-8 text-muted-foreground/60" }) }),
|
|
1525
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-muted-foreground", children: currentView === "SEARCH" ? "No files match your search" : currentView === "TRASH" ? "Trash is empty" : "This folder is empty" })
|
|
1488
1526
|
] });
|
|
1489
1527
|
}
|
|
1490
1528
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1529
|
+
isLoading && /* @__PURE__ */ jsx("div", { className: "h-1 w-full shrink-0", children: /* @__PURE__ */ jsx(
|
|
1530
|
+
Progress,
|
|
1531
|
+
{
|
|
1532
|
+
indeterminate: true,
|
|
1533
|
+
className: "h-full rounded-none bg-primary/10",
|
|
1534
|
+
indicatorClassName: "bg-primary"
|
|
1535
|
+
}
|
|
1536
|
+
) }),
|
|
1491
1537
|
/* @__PURE__ */ jsxs("div", { className: cn("flex-1 overflow-y-auto min-h-0 p-2 sm:p-3 md:p-4", className), children: [
|
|
1492
1538
|
/* @__PURE__ */ jsx("div", { className: "space-y-4 sm:space-y-6", children: Object.entries(groupedItems).map(([groupName, groupItems]) => /* @__PURE__ */ jsxs("div", { children: [
|
|
1493
1539
|
groupBy !== "NONE" && /* @__PURE__ */ jsxs("h3", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-2 sm:mb-3 px-1", children: [
|
|
@@ -1585,7 +1631,7 @@ var DriveFileGrid = (props) => {
|
|
|
1585
1631
|
)
|
|
1586
1632
|
] });
|
|
1587
1633
|
};
|
|
1588
|
-
var DriveHeader = () => {
|
|
1634
|
+
var DriveHeader = ({ className }) => {
|
|
1589
1635
|
const {
|
|
1590
1636
|
viewMode,
|
|
1591
1637
|
setViewMode,
|
|
@@ -1608,7 +1654,7 @@ var DriveHeader = () => {
|
|
|
1608
1654
|
createFolder
|
|
1609
1655
|
} = useDrive();
|
|
1610
1656
|
const [dialogs, setDialogs] = useState({ delete: false, emptyTrash: false, newFolder: false });
|
|
1611
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2
|
|
1657
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-wrap items-center gap-2 bg-muted/30 dark:bg-muted/20 p-2", className), children: [
|
|
1612
1658
|
currentView === "BROWSE" && /* @__PURE__ */ jsxs(
|
|
1613
1659
|
Button,
|
|
1614
1660
|
{
|
|
@@ -1878,6 +1924,18 @@ var DriveHeader = () => {
|
|
|
1878
1924
|
)
|
|
1879
1925
|
] });
|
|
1880
1926
|
};
|
|
1927
|
+
var DriveContentProgress = () => {
|
|
1928
|
+
const { isLoading } = useDrive();
|
|
1929
|
+
if (!isLoading) return null;
|
|
1930
|
+
return /* @__PURE__ */ jsx("div", { className: "h-1 w-full shrink-0", children: /* @__PURE__ */ jsx(
|
|
1931
|
+
Progress,
|
|
1932
|
+
{
|
|
1933
|
+
indeterminate: true,
|
|
1934
|
+
className: "h-full rounded-none bg-primary/10",
|
|
1935
|
+
indicatorClassName: "bg-primary"
|
|
1936
|
+
}
|
|
1937
|
+
) });
|
|
1938
|
+
};
|
|
1881
1939
|
var DroppablePathItem = (props) => {
|
|
1882
1940
|
const { id, name, isLast, onClick } = props;
|
|
1883
1941
|
const { currentFolderId } = useDrive();
|
|
@@ -1909,7 +1967,7 @@ var DroppablePathItem = (props) => {
|
|
|
1909
1967
|
variant: "ghost",
|
|
1910
1968
|
size: "sm",
|
|
1911
1969
|
className: cn(
|
|
1912
|
-
"h-
|
|
1970
|
+
"h-6 font-normal text-xs sm:text-sm px-1.5 sm:px-2 truncate max-w-25 sm:max-w-37.5",
|
|
1913
1971
|
isOver && !isCurrentFolder && "ring-2 ring-primary bg-primary/10 scale-105"
|
|
1914
1972
|
),
|
|
1915
1973
|
onClick,
|
|
@@ -1919,9 +1977,9 @@ var DroppablePathItem = (props) => {
|
|
|
1919
1977
|
}
|
|
1920
1978
|
);
|
|
1921
1979
|
};
|
|
1922
|
-
var DrivePathBar = () => {
|
|
1980
|
+
var DrivePathBar = ({ className }) => {
|
|
1923
1981
|
const { path, navigateToFolder } = useDrive();
|
|
1924
|
-
return /* @__PURE__ */ jsx("ol", { className: "flex items-center gap-1 sm:gap-1.5 text-sm text-muted-foreground
|
|
1982
|
+
return /* @__PURE__ */ jsx("ol", { className: cn("flex items-center gap-1 sm:gap-1.5 text-sm text-muted-foreground overflow-x-auto flex-nowrap min-w-0", className), "aria-label": "Breadcrumb", role: "navigation", children: path.map((item, index) => {
|
|
1925
1983
|
const isLast = index === path.length - 1;
|
|
1926
1984
|
return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-1 sm:gap-1.5 shrink-0", children: [
|
|
1927
1985
|
index > 0 && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/50 text-xs", "aria-hidden": "true", children: "/" }),
|
|
@@ -1937,33 +1995,8 @@ var DrivePathBar = () => {
|
|
|
1937
1995
|
] }, item.id ?? "root");
|
|
1938
1996
|
}) });
|
|
1939
1997
|
};
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
value,
|
|
1943
|
-
indicatorClassName,
|
|
1944
|
-
...props
|
|
1945
|
-
}) {
|
|
1946
|
-
return /* @__PURE__ */ jsx(
|
|
1947
|
-
ProgressPrimitive.Root,
|
|
1948
|
-
{
|
|
1949
|
-
"data-slot": "progress",
|
|
1950
|
-
className: cn(
|
|
1951
|
-
"bg-primary/20 relative h-2 w-full overflow-hidden rounded-full",
|
|
1952
|
-
className
|
|
1953
|
-
),
|
|
1954
|
-
...props,
|
|
1955
|
-
children: /* @__PURE__ */ jsx(
|
|
1956
|
-
ProgressPrimitive.Indicator,
|
|
1957
|
-
{
|
|
1958
|
-
"data-slot": "progress-indicator",
|
|
1959
|
-
className: cn("bg-primary h-full w-full flex-1 transition-all", indicatorClassName),
|
|
1960
|
-
style: { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
1961
|
-
}
|
|
1962
|
-
)
|
|
1963
|
-
}
|
|
1964
|
-
);
|
|
1965
|
-
}
|
|
1966
|
-
var UploadStatusIcon = ({ status }) => {
|
|
1998
|
+
var UploadStatusIcon = (props) => {
|
|
1999
|
+
const { status } = props;
|
|
1967
2000
|
switch (status) {
|
|
1968
2001
|
case "complete":
|
|
1969
2002
|
return /* @__PURE__ */ jsx(CheckCircle2, { className: "size-4 text-emerald-500" });
|
|
@@ -1982,7 +2015,7 @@ var DriveUpload = (props) => {
|
|
|
1982
2015
|
const [isDragging, setIsDragging] = useState(false);
|
|
1983
2016
|
const [showUploadsDialog, setShowUploadsDialog] = useState(false);
|
|
1984
2017
|
const inputRef = useRef(null);
|
|
1985
|
-
const { currentFolderId, setItems, apiEndpoint, activeAccountId, withCredentials } = useDrive();
|
|
2018
|
+
const { currentFolderId, setItems, apiEndpoint, activeAccountId, withCredentials, fetchItems, isLoading } = useDrive();
|
|
1986
2019
|
const { uploads, uploadFiles, cancelUpload, cancelAllUploads } = useUpload(apiEndpoint, activeAccountId, withCredentials, (uploadedItem) => {
|
|
1987
2020
|
if (uploadedItem) {
|
|
1988
2021
|
setItems((prev) => [uploadedItem, ...prev]);
|
|
@@ -2102,6 +2135,18 @@ var DriveUpload = (props) => {
|
|
|
2102
2135
|
"aria-hidden": "true"
|
|
2103
2136
|
}
|
|
2104
2137
|
),
|
|
2138
|
+
activeAccountId && /* @__PURE__ */ jsx(
|
|
2139
|
+
Button,
|
|
2140
|
+
{
|
|
2141
|
+
onClick: () => fetchItems(),
|
|
2142
|
+
type: "button",
|
|
2143
|
+
variant: "outline",
|
|
2144
|
+
size: "sm",
|
|
2145
|
+
disabled: isLoading,
|
|
2146
|
+
title: "Refresh",
|
|
2147
|
+
children: /* @__PURE__ */ jsx(RefreshCw, { className: cn("!size-4 shrink-0", isLoading && "animate-spin") })
|
|
2148
|
+
}
|
|
2149
|
+
),
|
|
2105
2150
|
/* @__PURE__ */ jsxs(
|
|
2106
2151
|
Button,
|
|
2107
2152
|
{
|
|
@@ -2110,8 +2155,8 @@ var DriveUpload = (props) => {
|
|
|
2110
2155
|
size: "sm",
|
|
2111
2156
|
disabled: hasUploadsInProgress,
|
|
2112
2157
|
children: [
|
|
2113
|
-
/* @__PURE__ */ jsx(Upload, { className: "size-4
|
|
2114
|
-
" Upload"
|
|
2158
|
+
/* @__PURE__ */ jsx(Upload, { className: "!size-4 shrink-0" }),
|
|
2159
|
+
/* @__PURE__ */ jsx("span", { children: "Upload" })
|
|
2115
2160
|
]
|
|
2116
2161
|
}
|
|
2117
2162
|
),
|
|
@@ -2123,8 +2168,8 @@ var DriveUpload = (props) => {
|
|
|
2123
2168
|
size: "sm",
|
|
2124
2169
|
onClick: () => setShowUploadsDialog(true),
|
|
2125
2170
|
children: [
|
|
2126
|
-
activeUploads.length > 0
|
|
2127
|
-
activeUploads.length > 0 ? `(${activeUploads.length})` : "Status"
|
|
2171
|
+
activeUploads.length > 0 ? /* @__PURE__ */ jsx(Loader2, { className: "!size-4 shrink-0 animate-spin" }) : /* @__PURE__ */ jsx(CheckCircle2, { className: "!size-4 shrink-0" }),
|
|
2172
|
+
/* @__PURE__ */ jsx("span", { children: activeUploads.length > 0 ? `(${activeUploads.length})` : "Status" })
|
|
2128
2173
|
]
|
|
2129
2174
|
}
|
|
2130
2175
|
)
|
|
@@ -2235,7 +2280,8 @@ var DriveStorageIndicator = (props) => {
|
|
|
2235
2280
|
] })
|
|
2236
2281
|
] });
|
|
2237
2282
|
};
|
|
2238
|
-
var ChooserSidebar = () => {
|
|
2283
|
+
var ChooserSidebar = (props) => {
|
|
2284
|
+
const { onNavigate } = props;
|
|
2239
2285
|
const {
|
|
2240
2286
|
accounts,
|
|
2241
2287
|
activeAccountId,
|
|
@@ -2243,14 +2289,20 @@ var ChooserSidebar = () => {
|
|
|
2243
2289
|
callAPI,
|
|
2244
2290
|
refreshAccounts,
|
|
2245
2291
|
currentView,
|
|
2246
|
-
setCurrentView
|
|
2292
|
+
setCurrentView,
|
|
2293
|
+
availableProviders
|
|
2247
2294
|
} = useDrive();
|
|
2248
2295
|
const [renameDialog, setRenameDialog] = useState({ open: false, account: null });
|
|
2249
2296
|
const [deleteDialog, setDeleteDialog] = useState({ open: false, account: null });
|
|
2250
2297
|
const [newName, setNewName] = useState("");
|
|
2298
|
+
const [oauthLoading, setOauthLoading] = useState(false);
|
|
2299
|
+
const [oauthAbort, setOauthAbort] = useState(null);
|
|
2300
|
+
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
2251
2301
|
const currentAccount = activeAccountId ? accounts.find((a) => a.id === activeAccountId) : null;
|
|
2252
2302
|
const currentAccountName = currentAccount?.name || "Local Storage";
|
|
2253
2303
|
const currentAccountEmail = currentAccount?.email || "On this device";
|
|
2304
|
+
const hasAnyProvider = availableProviders.google;
|
|
2305
|
+
const isDropdownDisabled = accounts.length === 0 && !hasAnyProvider;
|
|
2254
2306
|
const handleRename = async () => {
|
|
2255
2307
|
if (!renameDialog.account || !newName.trim()) return;
|
|
2256
2308
|
await callAPI("renameAccount", { method: "PATCH", query: { id: renameDialog.account.id }, body: JSON.stringify({ name: newName.trim() }) });
|
|
@@ -2266,90 +2318,157 @@ var ChooserSidebar = () => {
|
|
|
2266
2318
|
setDeleteDialog({ open: false, account: null });
|
|
2267
2319
|
return [true];
|
|
2268
2320
|
};
|
|
2269
|
-
const openOAuthPopup =
|
|
2270
|
-
const res = await callAPI("getAuthUrl", { query: { provider: "GOOGLE" } });
|
|
2271
|
-
if (res.status !== 200 || !res.data?.url) {
|
|
2272
|
-
alert(res.message || "Failed");
|
|
2273
|
-
return;
|
|
2274
|
-
}
|
|
2321
|
+
const openOAuthPopup = () => {
|
|
2275
2322
|
const width = 600, height = 600;
|
|
2276
2323
|
const left = window.screen.width / 2 - width / 2;
|
|
2277
2324
|
const top = window.screen.height / 2 - height / 2;
|
|
2278
|
-
window.open(
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
}
|
|
2283
|
-
const
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2325
|
+
const popup = window.open("about:blank", "Connect to Google Drive", `width=${width},height=${height},top=${top},left=${left}`);
|
|
2326
|
+
if (!popup) {
|
|
2327
|
+
alert("Popup blocked. Please allow popups for this site.");
|
|
2328
|
+
return;
|
|
2329
|
+
}
|
|
2330
|
+
const controller = new AbortController();
|
|
2331
|
+
setOauthAbort(controller);
|
|
2332
|
+
setOauthLoading(true);
|
|
2333
|
+
(async () => {
|
|
2334
|
+
try {
|
|
2335
|
+
const res = await callAPI("getAuthUrl", { query: { provider: "GOOGLE" } });
|
|
2336
|
+
if (controller.signal.aborted) {
|
|
2337
|
+
popup.close();
|
|
2338
|
+
return;
|
|
2339
|
+
}
|
|
2340
|
+
if (res.status !== 200 || !res.data?.url) {
|
|
2341
|
+
popup.close();
|
|
2342
|
+
setOauthLoading(false);
|
|
2343
|
+
setOauthAbort(null);
|
|
2344
|
+
alert(res.message || "Failed to initialize account connection");
|
|
2345
|
+
return;
|
|
2346
|
+
}
|
|
2347
|
+
popup.location.href = res.data.url;
|
|
2348
|
+
const cleanup = () => {
|
|
2349
|
+
window.removeEventListener("message", ml);
|
|
2350
|
+
window.removeEventListener("storage", sl);
|
|
2351
|
+
setOauthLoading(false);
|
|
2352
|
+
setOauthAbort(null);
|
|
2353
|
+
};
|
|
2354
|
+
const ml = (e) => {
|
|
2355
|
+
if (e.data === "oauth-success") {
|
|
2356
|
+
cleanup();
|
|
2357
|
+
refreshAccounts();
|
|
2358
|
+
setDropdownOpen(true);
|
|
2359
|
+
}
|
|
2360
|
+
};
|
|
2361
|
+
const sl = (e) => {
|
|
2362
|
+
if (e.key === "next-drive-oauth-success") {
|
|
2363
|
+
cleanup();
|
|
2364
|
+
refreshAccounts();
|
|
2365
|
+
setDropdownOpen(true);
|
|
2366
|
+
}
|
|
2367
|
+
};
|
|
2368
|
+
window.addEventListener("message", ml);
|
|
2369
|
+
window.addEventListener("storage", sl);
|
|
2370
|
+
const checkPopupClosed = setInterval(() => {
|
|
2371
|
+
if (popup.closed) {
|
|
2372
|
+
clearInterval(checkPopupClosed);
|
|
2373
|
+
cleanup();
|
|
2374
|
+
}
|
|
2375
|
+
}, 500);
|
|
2376
|
+
} catch {
|
|
2377
|
+
popup.close();
|
|
2378
|
+
setOauthLoading(false);
|
|
2379
|
+
setOauthAbort(null);
|
|
2380
|
+
alert("Failed to connect. Please try again.");
|
|
2293
2381
|
}
|
|
2294
|
-
};
|
|
2295
|
-
|
|
2296
|
-
|
|
2382
|
+
})();
|
|
2383
|
+
};
|
|
2384
|
+
const cancelOAuth = () => {
|
|
2385
|
+
oauthAbort?.abort();
|
|
2386
|
+
setOauthLoading(false);
|
|
2387
|
+
setOauthAbort(null);
|
|
2297
2388
|
};
|
|
2298
2389
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full w-full bg-muted/5 dark:bg-muted/10", children: [
|
|
2299
|
-
/* @__PURE__ */ jsx("div", { className: "p-2 border-b border-border/50", children: /* @__PURE__ */ jsxs(
|
|
2300
|
-
|
|
2301
|
-
/*
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
activeAccountId ? "bg-blue-500/10 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400" : "bg-emerald-500/10 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-400"
|
|
2305
|
-
), children: activeAccountId ? /* @__PURE__ */ jsx(Database, { className: "size-3.5" }) : /* @__PURE__ */ jsx(HardDrive, { className: "size-3.5" }) }),
|
|
2390
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 border-b border-border/50", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2391
|
+
isDropdownDisabled ? (
|
|
2392
|
+
/* Static display when no accounts and no providers */
|
|
2393
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex items-center gap-2 px-2 h-11 min-w-0", children: [
|
|
2394
|
+
/* @__PURE__ */ jsx("div", { className: "size-7 rounded-md flex items-center justify-center shrink-0 bg-emerald-500/10 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-400", children: /* @__PURE__ */ jsx(HardDrive, { className: "size-3.5" }) }),
|
|
2306
2395
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
2307
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium truncate", children:
|
|
2308
|
-
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground truncate", children:
|
|
2396
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium truncate", children: "Local Storage" }),
|
|
2397
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground truncate", children: "On this device" })
|
|
2309
2398
|
] })
|
|
2310
|
-
] })
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2399
|
+
] })
|
|
2400
|
+
) : /* @__PURE__ */ jsxs(DropdownMenu, { open: dropdownOpen, onOpenChange: setDropdownOpen, children: [
|
|
2401
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", className: "flex-1 min-w-0 justify-between px-2 h-11 hover:bg-muted/50 dark:hover:bg-muted/30", children: [
|
|
2402
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-left min-w-0 flex-1", children: [
|
|
2403
|
+
/* @__PURE__ */ jsx("div", { className: cn(
|
|
2404
|
+
"size-7 rounded-md flex items-center justify-center shrink-0",
|
|
2405
|
+
activeAccountId ? "bg-blue-500/10 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400" : "bg-emerald-500/10 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-400"
|
|
2406
|
+
), children: activeAccountId ? /* @__PURE__ */ jsx(Database, { className: "size-3.5" }) : /* @__PURE__ */ jsx(HardDrive, { className: "size-3.5" }) }),
|
|
2407
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
2408
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium truncate", children: currentAccountName }),
|
|
2409
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground truncate", children: currentAccountEmail })
|
|
2410
|
+
] })
|
|
2411
|
+
] }),
|
|
2412
|
+
/* @__PURE__ */ jsx(ChevronsUpDown, { className: "size-3.5 text-muted-foreground/60 shrink-0" })
|
|
2413
|
+
] }) }),
|
|
2414
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { className: "w-56", align: "start", children: [
|
|
2415
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-[11px] font-medium text-muted-foreground uppercase tracking-wide", children: "Storage" }),
|
|
2416
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: () => {
|
|
2417
|
+
setActiveAccountId(null);
|
|
2418
|
+
setCurrentView("BROWSE");
|
|
2419
|
+
onNavigate?.();
|
|
2420
|
+
}, className: "gap-2 py-2", children: [
|
|
2421
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm", children: "Local Storage" }),
|
|
2422
|
+
activeAccountId === null && /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-primary" })
|
|
2327
2423
|
] }),
|
|
2328
|
-
/* @__PURE__ */
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2424
|
+
accounts.length > 0 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
2425
|
+
accounts.map((account) => /* @__PURE__ */ jsxs(
|
|
2426
|
+
DropdownMenuItem,
|
|
2427
|
+
{
|
|
2428
|
+
onClick: () => {
|
|
2429
|
+
setActiveAccountId(account.id);
|
|
2430
|
+
setCurrentView("BROWSE");
|
|
2431
|
+
onNavigate?.();
|
|
2432
|
+
},
|
|
2433
|
+
className: "gap-2 py-2",
|
|
2434
|
+
children: [
|
|
2435
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2436
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm truncate", children: account.name }),
|
|
2437
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground truncate", children: account.email })
|
|
2438
|
+
] }),
|
|
2439
|
+
activeAccountId === account.id && /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-primary" })
|
|
2440
|
+
]
|
|
2441
|
+
},
|
|
2442
|
+
account.id
|
|
2443
|
+
)),
|
|
2444
|
+
hasAnyProvider && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2445
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
2446
|
+
/* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
|
|
2447
|
+
/* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { className: "gap-2", children: [
|
|
2448
|
+
/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }),
|
|
2449
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: "Add Account" })
|
|
2337
2450
|
] }),
|
|
2338
|
-
/* @__PURE__ */ jsx(
|
|
2339
|
-
/* @__PURE__ */ jsxs(DropdownMenuItem, { className: "text-destructive focus:text-destructive", onClick: () => setDeleteDialog({ open: true, account }), children: [
|
|
2340
|
-
/* @__PURE__ */ jsx(Trash, { className: "size-3.5 mr-2" }),
|
|
2341
|
-
" Remove"
|
|
2342
|
-
] })
|
|
2451
|
+
/* @__PURE__ */ jsx(DropdownMenuSubContent, { children: availableProviders.google && /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: openOAuthPopup, children: "Google Drive" }) })
|
|
2343
2452
|
] })
|
|
2344
2453
|
] })
|
|
2345
|
-
] }
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2454
|
+
] })
|
|
2455
|
+
] }),
|
|
2456
|
+
currentAccount && /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
2457
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "size-9 shrink-0 hover:bg-muted/50 dark:hover:bg-muted/30", children: /* @__PURE__ */ jsx(Settings2, { className: "size-4 text-muted-foreground" }) }) }),
|
|
2458
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-40", children: [
|
|
2459
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-xs text-muted-foreground truncate", children: currentAccount.name }),
|
|
2460
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
2461
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: () => {
|
|
2462
|
+
setNewName(currentAccount.name);
|
|
2463
|
+
setRenameDialog({ open: true, account: currentAccount });
|
|
2464
|
+
}, children: [
|
|
2465
|
+
/* @__PURE__ */ jsx(Pencil, { className: "size-3.5 mr-2" }),
|
|
2466
|
+
" Rename"
|
|
2351
2467
|
] }),
|
|
2352
|
-
/* @__PURE__ */
|
|
2468
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { className: "text-destructive focus:text-destructive", onClick: () => setDeleteDialog({ open: true, account: currentAccount }), children: [
|
|
2469
|
+
/* @__PURE__ */ jsx(Trash, { className: "size-3.5 mr-2" }),
|
|
2470
|
+
" Disconnect"
|
|
2471
|
+
] })
|
|
2353
2472
|
] })
|
|
2354
2473
|
] })
|
|
2355
2474
|
] }) }),
|
|
@@ -2359,7 +2478,10 @@ var ChooserSidebar = () => {
|
|
|
2359
2478
|
{
|
|
2360
2479
|
variant: "ghost",
|
|
2361
2480
|
className: cn("w-full justify-start gap-2.5 h-9 px-2.5 font-medium", currentView !== "TRASH" ? "bg-primary/10 text-primary hover:bg-primary/15" : "hover:bg-muted/50"),
|
|
2362
|
-
onClick: () =>
|
|
2481
|
+
onClick: () => {
|
|
2482
|
+
setCurrentView("BROWSE");
|
|
2483
|
+
onNavigate?.();
|
|
2484
|
+
},
|
|
2363
2485
|
children: [
|
|
2364
2486
|
/* @__PURE__ */ jsx(FolderOpen, { className: "size-4" }),
|
|
2365
2487
|
" My Files"
|
|
@@ -2371,7 +2493,10 @@ var ChooserSidebar = () => {
|
|
|
2371
2493
|
{
|
|
2372
2494
|
variant: "ghost",
|
|
2373
2495
|
className: cn("w-full justify-start gap-2.5 h-9 px-2.5 font-medium", currentView === "TRASH" ? "bg-destructive/10 text-destructive hover:bg-destructive/15" : "hover:bg-muted/50"),
|
|
2374
|
-
onClick: () =>
|
|
2496
|
+
onClick: () => {
|
|
2497
|
+
setCurrentView("TRASH");
|
|
2498
|
+
onNavigate?.();
|
|
2499
|
+
},
|
|
2375
2500
|
children: [
|
|
2376
2501
|
/* @__PURE__ */ jsx(Trash2, { className: "size-4" }),
|
|
2377
2502
|
" Trash"
|
|
@@ -2380,7 +2505,7 @@ var ChooserSidebar = () => {
|
|
|
2380
2505
|
)
|
|
2381
2506
|
] }),
|
|
2382
2507
|
/* @__PURE__ */ jsx("div", { className: "p-2.5 border-t border-border/50 bg-background/50 dark:bg-background/30", children: /* @__PURE__ */ jsx(DriveStorageIndicator, {}) }),
|
|
2383
|
-
/* @__PURE__ */ jsx(Dialog, { open: renameDialog.open, onOpenChange: (open) => !open && setRenameDialog({ open: false, account: null }), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-sm", children: [
|
|
2508
|
+
/* @__PURE__ */ jsx(Dialog, { open: renameDialog.open, onOpenChange: (open) => !open && setRenameDialog({ open: false, account: null }), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-sm", showCloseButton: false, children: [
|
|
2384
2509
|
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
2385
2510
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Rename Account" }),
|
|
2386
2511
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Enter a new display name." })
|
|
@@ -2396,21 +2521,32 @@ var ChooserSidebar = () => {
|
|
|
2396
2521
|
{
|
|
2397
2522
|
open: deleteDialog.open,
|
|
2398
2523
|
onClose: () => setDeleteDialog({ open: false, account: null }),
|
|
2399
|
-
title: "
|
|
2400
|
-
description: `Disconnect "${deleteDialog.account?.name}"?
|
|
2524
|
+
title: "Disconnect Account",
|
|
2525
|
+
description: `Disconnect "${deleteDialog.account?.name}"? Access will be revoked and synced files will be removed.`,
|
|
2401
2526
|
onConfirm: handleDelete
|
|
2402
2527
|
}
|
|
2403
|
-
)
|
|
2528
|
+
),
|
|
2529
|
+
/* @__PURE__ */ jsx(Dialog, { open: oauthLoading, onOpenChange: (open) => !open && cancelOAuth(), children: /* @__PURE__ */ jsx(DialogContent, { className: "sm:max-w-xs", showCloseButton: false, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 py-4", children: [
|
|
2530
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-8 text-primary animate-spin" }),
|
|
2531
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2532
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "text-base", children: "Connecting..." }),
|
|
2533
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "text-sm mt-1", children: "Preparing Google authentication" })
|
|
2534
|
+
] }),
|
|
2535
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: cancelOAuth, children: "Cancel" })
|
|
2536
|
+
] }) }) })
|
|
2537
|
+
] });
|
|
2538
|
+
};
|
|
2539
|
+
var MobileSidebarSheet = () => {
|
|
2540
|
+
const [sheetOpen, setSheetOpen] = useState(false);
|
|
2541
|
+
return /* @__PURE__ */ jsxs(Sheet, { open: sheetOpen, onOpenChange: setSheetOpen, children: [
|
|
2542
|
+
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "size-9 md:hidden shrink-0", children: /* @__PURE__ */ jsx(Menu, { className: "size-5" }) }) }),
|
|
2543
|
+
/* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "w-72 p-0", hideCloseButton: true, children: [
|
|
2544
|
+
/* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Navigation" }),
|
|
2545
|
+
/* @__PURE__ */ jsx(SheetDescription, { className: "sr-only", children: "Storage and navigation" }),
|
|
2546
|
+
/* @__PURE__ */ jsx(ChooserSidebar, { onNavigate: () => setSheetOpen(false) })
|
|
2547
|
+
] })
|
|
2404
2548
|
] });
|
|
2405
2549
|
};
|
|
2406
|
-
var MobileSidebarSheet = () => /* @__PURE__ */ jsxs(Sheet, { children: [
|
|
2407
|
-
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "size-9 md:hidden shrink-0", children: /* @__PURE__ */ jsx(Menu, { className: "size-5" }) }) }),
|
|
2408
|
-
/* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "w-72 p-0", children: [
|
|
2409
|
-
/* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Navigation" }),
|
|
2410
|
-
/* @__PURE__ */ jsx(SheetDescription, { className: "sr-only", children: "Storage and navigation" }),
|
|
2411
|
-
/* @__PURE__ */ jsx(ChooserSidebar, {})
|
|
2412
|
-
] })
|
|
2413
|
-
] });
|
|
2414
2550
|
var DriveFileChooser = (props) => {
|
|
2415
2551
|
const {
|
|
2416
2552
|
value,
|
|
@@ -2522,9 +2658,9 @@ var DriveFileChooser = (props) => {
|
|
|
2522
2658
|
/* @__PURE__ */ jsxs(Dialog2Body, { className: "flex flex-col md:flex-row", children: [
|
|
2523
2659
|
/* @__PURE__ */ jsx("div", { className: "hidden md:flex w-52 lg:w-56 border-r shrink-0", children: /* @__PURE__ */ jsx(ChooserSidebar, {}) }),
|
|
2524
2660
|
/* @__PURE__ */ jsx(DriveDndProvider, { children: /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col min-w-0 min-h-0", children: [
|
|
2525
|
-
/* @__PURE__ */ jsx(
|
|
2526
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2527
|
-
/* @__PURE__ */ jsx(
|
|
2661
|
+
/* @__PURE__ */ jsx(DriveHeader, { className: "border-b" }),
|
|
2662
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b bg-muted/20 dark:bg-muted/10", children: [
|
|
2663
|
+
/* @__PURE__ */ jsx(DrivePathBar, { className: "flex-1" }),
|
|
2528
2664
|
/* @__PURE__ */ jsx(DriveUpload, { compact: true, accept })
|
|
2529
2665
|
] }),
|
|
2530
2666
|
/* @__PURE__ */ jsx(DriveFileGrid, { mimeFilter: accept, className: "flex-1" })
|
|
@@ -2540,7 +2676,8 @@ var DriveFileChooser = (props) => {
|
|
|
2540
2676
|
] }) })
|
|
2541
2677
|
] });
|
|
2542
2678
|
};
|
|
2543
|
-
var SidebarContent = (
|
|
2679
|
+
var SidebarContent = (props) => {
|
|
2680
|
+
const { onNavigate } = props;
|
|
2544
2681
|
const {
|
|
2545
2682
|
accounts,
|
|
2546
2683
|
activeAccountId,
|
|
@@ -2549,7 +2686,7 @@ var SidebarContent = ({ onNavigate }) => {
|
|
|
2549
2686
|
refreshAccounts,
|
|
2550
2687
|
currentView,
|
|
2551
2688
|
setCurrentView,
|
|
2552
|
-
|
|
2689
|
+
availableProviders
|
|
2553
2690
|
} = useDrive();
|
|
2554
2691
|
const [renameDialog, setRenameDialog] = useState({
|
|
2555
2692
|
open: false,
|
|
@@ -2560,9 +2697,14 @@ var SidebarContent = ({ onNavigate }) => {
|
|
|
2560
2697
|
account: null
|
|
2561
2698
|
});
|
|
2562
2699
|
const [newName, setNewName] = useState("");
|
|
2700
|
+
const [oauthLoading, setOauthLoading] = useState(false);
|
|
2701
|
+
const [oauthAbort, setOauthAbort] = useState(null);
|
|
2702
|
+
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
2563
2703
|
const currentAccount = activeAccountId ? accounts.find((a) => a.id === activeAccountId) : null;
|
|
2564
2704
|
const currentAccountName = currentAccount?.name || "Local Storage";
|
|
2565
2705
|
const currentAccountEmail = currentAccount?.email || "On this device";
|
|
2706
|
+
const hasAnyProvider = availableProviders.google;
|
|
2707
|
+
const isDropdownDisabled = accounts.length === 0 && !hasAnyProvider;
|
|
2566
2708
|
const handleRename = async () => {
|
|
2567
2709
|
if (!renameDialog.account || !newName.trim()) return;
|
|
2568
2710
|
await callAPI("renameAccount", {
|
|
@@ -2582,68 +2724,111 @@ var SidebarContent = ({ onNavigate }) => {
|
|
|
2582
2724
|
setDeleteDialog({ open: false, account: null });
|
|
2583
2725
|
return [true];
|
|
2584
2726
|
};
|
|
2585
|
-
const openOAuthPopup =
|
|
2586
|
-
const res = await callAPI("getAuthUrl", { query: { provider: "GOOGLE" } });
|
|
2587
|
-
if (res.status !== 200 || !res.data?.url) {
|
|
2588
|
-
alert(res.message || "Failed to initialize account connection");
|
|
2589
|
-
return;
|
|
2590
|
-
}
|
|
2727
|
+
const openOAuthPopup = () => {
|
|
2591
2728
|
const width = 600, height = 600;
|
|
2592
2729
|
const left = window.screen.width / 2 - width / 2;
|
|
2593
2730
|
const top = window.screen.height / 2 - height / 2;
|
|
2594
|
-
window.open(
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
}
|
|
2599
|
-
const
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2731
|
+
const popup = window.open("about:blank", "Connect to Google Drive", `width=${width},height=${height},top=${top},left=${left}`);
|
|
2732
|
+
if (!popup) {
|
|
2733
|
+
alert("Popup blocked. Please allow popups for this site.");
|
|
2734
|
+
return;
|
|
2735
|
+
}
|
|
2736
|
+
const controller = new AbortController();
|
|
2737
|
+
setOauthAbort(controller);
|
|
2738
|
+
setOauthLoading(true);
|
|
2739
|
+
(async () => {
|
|
2740
|
+
try {
|
|
2741
|
+
const res = await callAPI("getAuthUrl", { query: { provider: "GOOGLE" } });
|
|
2742
|
+
if (controller.signal.aborted) {
|
|
2743
|
+
popup.close();
|
|
2744
|
+
return;
|
|
2745
|
+
}
|
|
2746
|
+
if (res.status !== 200 || !res.data?.url) {
|
|
2747
|
+
popup.close();
|
|
2748
|
+
setOauthLoading(false);
|
|
2749
|
+
setOauthAbort(null);
|
|
2750
|
+
alert(res.message || "Failed to initialize account connection");
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2753
|
+
popup.location.href = res.data.url;
|
|
2754
|
+
const cleanup = () => {
|
|
2755
|
+
window.removeEventListener("message", messageListener);
|
|
2756
|
+
window.removeEventListener("storage", storageListener);
|
|
2757
|
+
setOauthLoading(false);
|
|
2758
|
+
setOauthAbort(null);
|
|
2759
|
+
};
|
|
2760
|
+
const messageListener = (event) => {
|
|
2761
|
+
if (event.data === "oauth-success") {
|
|
2762
|
+
cleanup();
|
|
2763
|
+
refreshAccounts();
|
|
2764
|
+
setDropdownOpen(true);
|
|
2765
|
+
}
|
|
2766
|
+
};
|
|
2767
|
+
const storageListener = (event) => {
|
|
2768
|
+
if (event.key === "next-drive-oauth-success") {
|
|
2769
|
+
cleanup();
|
|
2770
|
+
refreshAccounts();
|
|
2771
|
+
setDropdownOpen(true);
|
|
2772
|
+
}
|
|
2773
|
+
};
|
|
2774
|
+
window.addEventListener("message", messageListener);
|
|
2775
|
+
window.addEventListener("storage", storageListener);
|
|
2776
|
+
const checkPopupClosed = setInterval(() => {
|
|
2777
|
+
if (popup.closed) {
|
|
2778
|
+
clearInterval(checkPopupClosed);
|
|
2779
|
+
cleanup();
|
|
2780
|
+
}
|
|
2781
|
+
}, 500);
|
|
2782
|
+
} catch (err) {
|
|
2783
|
+
popup.close();
|
|
2784
|
+
setOauthLoading(false);
|
|
2785
|
+
setOauthAbort(null);
|
|
2786
|
+
alert("Failed to connect. Please try again.");
|
|
2609
2787
|
}
|
|
2610
|
-
};
|
|
2611
|
-
|
|
2612
|
-
|
|
2788
|
+
})();
|
|
2789
|
+
};
|
|
2790
|
+
const cancelOAuth = () => {
|
|
2791
|
+
oauthAbort?.abort();
|
|
2792
|
+
setOauthLoading(false);
|
|
2793
|
+
setOauthAbort(null);
|
|
2613
2794
|
};
|
|
2614
2795
|
return /* @__PURE__ */ jsxs("div", { className: "w-full h-full flex flex-col bg-muted/5 dark:bg-muted/10", children: [
|
|
2615
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
indicatorClassName: "animate-pulse bg-primary/60"
|
|
2621
|
-
}
|
|
2622
|
-
) }),
|
|
2623
|
-
/* @__PURE__ */ jsx("div", { className: "p-2 border-b border-border/50", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
2624
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", className: "w-full justify-between px-2 h-11 hover:bg-muted/50 dark:hover:bg-muted/30", children: [
|
|
2625
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 text-left min-w-0 flex-1", children: [
|
|
2626
|
-
/* @__PURE__ */ jsx("div", { className: cn(
|
|
2627
|
-
"size-7 rounded-md flex items-center justify-center shrink-0",
|
|
2628
|
-
activeAccountId ? "bg-blue-500/10 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400" : "bg-emerald-500/10 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-400"
|
|
2629
|
-
), children: activeAccountId ? /* @__PURE__ */ jsx(Database, { className: "size-3.5" }) : /* @__PURE__ */ jsx(HardDrive, { className: "size-3.5" }) }),
|
|
2796
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 border-b border-border/50", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2797
|
+
isDropdownDisabled ? (
|
|
2798
|
+
/* Static display when no accounts and no providers */
|
|
2799
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex items-center gap-2.5 px-2 h-11 min-w-0", children: [
|
|
2800
|
+
/* @__PURE__ */ jsx("div", { className: "size-7 rounded-md flex items-center justify-center shrink-0 bg-emerald-500/10 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-400", children: /* @__PURE__ */ jsx(HardDrive, { className: "size-3.5" }) }),
|
|
2630
2801
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
2631
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium truncate", children:
|
|
2632
|
-
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground truncate", children:
|
|
2802
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium truncate", children: "Local Storage" }),
|
|
2803
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground truncate", children: "On this device" })
|
|
2633
2804
|
] })
|
|
2634
|
-
] })
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2805
|
+
] })
|
|
2806
|
+
) : /* @__PURE__ */ jsxs(DropdownMenu, { open: dropdownOpen, onOpenChange: setDropdownOpen, children: [
|
|
2807
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", className: "flex-1 min-w-0 justify-between px-2 h-11 hover:bg-muted/50 dark:hover:bg-muted/30", children: [
|
|
2808
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 text-left min-w-0 flex-1", children: [
|
|
2809
|
+
/* @__PURE__ */ jsx("div", { className: cn(
|
|
2810
|
+
"size-7 rounded-md flex items-center justify-center shrink-0",
|
|
2811
|
+
activeAccountId ? "bg-blue-500/10 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400" : "bg-emerald-500/10 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-400"
|
|
2812
|
+
), children: activeAccountId ? /* @__PURE__ */ jsx(Database, { className: "size-3.5" }) : /* @__PURE__ */ jsx(HardDrive, { className: "size-3.5" }) }),
|
|
2813
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
2814
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium truncate", children: currentAccountName }),
|
|
2815
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground truncate", children: currentAccountEmail })
|
|
2816
|
+
] })
|
|
2817
|
+
] }),
|
|
2818
|
+
/* @__PURE__ */ jsx(ChevronsUpDown, { className: "size-3.5 text-muted-foreground/60 shrink-0" })
|
|
2819
|
+
] }) }),
|
|
2820
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { className: "w-56", align: "start", children: [
|
|
2821
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-[11px] font-medium text-muted-foreground uppercase tracking-wide", children: "Storage" }),
|
|
2822
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: () => {
|
|
2823
|
+
setActiveAccountId(null);
|
|
2824
|
+
setCurrentView("BROWSE");
|
|
2825
|
+
onNavigate?.();
|
|
2826
|
+
}, className: "gap-2 py-2", children: [
|
|
2827
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm", children: "Local Storage" }),
|
|
2828
|
+
activeAccountId === null && /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-primary" })
|
|
2829
|
+
] }),
|
|
2830
|
+
accounts.length > 0 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
2831
|
+
accounts.map((account) => /* @__PURE__ */ jsxs(
|
|
2647
2832
|
DropdownMenuItem,
|
|
2648
2833
|
{
|
|
2649
2834
|
onClick: () => {
|
|
@@ -2651,7 +2836,7 @@ var SidebarContent = ({ onNavigate }) => {
|
|
|
2651
2836
|
setCurrentView("BROWSE");
|
|
2652
2837
|
onNavigate?.();
|
|
2653
2838
|
},
|
|
2654
|
-
className: "
|
|
2839
|
+
className: "gap-2 py-2",
|
|
2655
2840
|
children: [
|
|
2656
2841
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2657
2842
|
/* @__PURE__ */ jsx("p", { className: "text-sm truncate", children: account.name }),
|
|
@@ -2659,49 +2844,52 @@ var SidebarContent = ({ onNavigate }) => {
|
|
|
2659
2844
|
] }),
|
|
2660
2845
|
activeAccountId === account.id && /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-primary" })
|
|
2661
2846
|
]
|
|
2662
|
-
}
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
className: "
|
|
2671
|
-
onClick: (e) => e.stopPropagation(),
|
|
2672
|
-
children: /* @__PURE__ */ jsx(Settings2, { className: "size-3.5 text-muted-foreground" })
|
|
2673
|
-
}
|
|
2674
|
-
) }),
|
|
2675
|
-
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-36", children: [
|
|
2676
|
-
/* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: () => {
|
|
2677
|
-
setNewName(account.name);
|
|
2678
|
-
setRenameDialog({ open: true, account });
|
|
2679
|
-
}, children: [
|
|
2680
|
-
/* @__PURE__ */ jsx(Pencil, { className: "size-3.5 mr-2" }),
|
|
2681
|
-
"Rename"
|
|
2847
|
+
},
|
|
2848
|
+
account.id
|
|
2849
|
+
)),
|
|
2850
|
+
hasAnyProvider && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2851
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
2852
|
+
/* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
|
|
2853
|
+
/* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { className: "gap-2", children: [
|
|
2854
|
+
/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }),
|
|
2855
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: "Add Account" })
|
|
2682
2856
|
] }),
|
|
2683
|
-
/* @__PURE__ */ jsx(
|
|
2684
|
-
/* @__PURE__ */ jsxs(
|
|
2685
|
-
DropdownMenuItem,
|
|
2686
|
-
{
|
|
2687
|
-
className: "text-destructive focus:text-destructive",
|
|
2688
|
-
onClick: () => setDeleteDialog({ open: true, account }),
|
|
2689
|
-
children: [
|
|
2690
|
-
/* @__PURE__ */ jsx(Trash, { className: "size-3.5 mr-2" }),
|
|
2691
|
-
"Remove"
|
|
2692
|
-
]
|
|
2693
|
-
}
|
|
2694
|
-
)
|
|
2857
|
+
/* @__PURE__ */ jsx(DropdownMenuSubContent, { children: availableProviders.google && /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: openOAuthPopup, children: "Google Drive" }) })
|
|
2695
2858
|
] })
|
|
2696
2859
|
] })
|
|
2697
|
-
] }
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2860
|
+
] })
|
|
2861
|
+
] }),
|
|
2862
|
+
currentAccount && /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
2863
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
2864
|
+
Button,
|
|
2865
|
+
{
|
|
2866
|
+
variant: "ghost",
|
|
2867
|
+
size: "icon",
|
|
2868
|
+
className: "size-9 shrink-0 hover:bg-muted/50 dark:hover:bg-muted/30",
|
|
2869
|
+
children: /* @__PURE__ */ jsx(Settings2, { className: "size-4 text-muted-foreground" })
|
|
2870
|
+
}
|
|
2871
|
+
) }),
|
|
2872
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-40", children: [
|
|
2873
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-xs text-muted-foreground truncate", children: currentAccount.name }),
|
|
2874
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
2875
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: () => {
|
|
2876
|
+
setNewName(currentAccount.name);
|
|
2877
|
+
setRenameDialog({ open: true, account: currentAccount });
|
|
2878
|
+
}, children: [
|
|
2879
|
+
/* @__PURE__ */ jsx(Pencil, { className: "size-3.5 mr-2" }),
|
|
2880
|
+
"Rename"
|
|
2703
2881
|
] }),
|
|
2704
|
-
/* @__PURE__ */
|
|
2882
|
+
/* @__PURE__ */ jsxs(
|
|
2883
|
+
DropdownMenuItem,
|
|
2884
|
+
{
|
|
2885
|
+
className: "text-destructive focus:text-destructive",
|
|
2886
|
+
onClick: () => setDeleteDialog({ open: true, account: currentAccount }),
|
|
2887
|
+
children: [
|
|
2888
|
+
/* @__PURE__ */ jsx(Trash, { className: "size-3.5 mr-2" }),
|
|
2889
|
+
"Disconnect"
|
|
2890
|
+
]
|
|
2891
|
+
}
|
|
2892
|
+
)
|
|
2705
2893
|
] })
|
|
2706
2894
|
] })
|
|
2707
2895
|
] }) }),
|
|
@@ -2744,7 +2932,7 @@ var SidebarContent = ({ onNavigate }) => {
|
|
|
2744
2932
|
)
|
|
2745
2933
|
] }),
|
|
2746
2934
|
/* @__PURE__ */ jsx("div", { className: "p-2.5 border-t border-border/50 bg-background/50 dark:bg-background/30", children: /* @__PURE__ */ jsx(DriveStorageIndicator, {}) }),
|
|
2747
|
-
/* @__PURE__ */ jsx(Dialog, { open: renameDialog.open, onOpenChange: (open) => !open && setRenameDialog({ open: false, account: null }), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-sm", children: [
|
|
2935
|
+
/* @__PURE__ */ jsx(Dialog, { open: renameDialog.open, onOpenChange: (open) => !open && setRenameDialog({ open: false, account: null }), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-sm", showCloseButton: false, children: [
|
|
2748
2936
|
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
2749
2937
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Rename Account" }),
|
|
2750
2938
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Enter a new display name for this storage account." })
|
|
@@ -2768,37 +2956,34 @@ var SidebarContent = ({ onNavigate }) => {
|
|
|
2768
2956
|
{
|
|
2769
2957
|
open: deleteDialog.open,
|
|
2770
2958
|
onClose: () => setDeleteDialog({ open: false, account: null }),
|
|
2771
|
-
title: "
|
|
2772
|
-
description: `Are you sure you want to disconnect "${deleteDialog.account?.name}"?
|
|
2959
|
+
title: "Disconnect Account",
|
|
2960
|
+
description: `Are you sure you want to disconnect "${deleteDialog.account?.name}"? Access will be revoked and synced files will be removed from local cache.`,
|
|
2773
2961
|
onConfirm: handleDelete
|
|
2774
2962
|
}
|
|
2775
|
-
)
|
|
2963
|
+
),
|
|
2964
|
+
/* @__PURE__ */ jsx(Dialog, { open: oauthLoading, onOpenChange: (open) => !open && cancelOAuth(), children: /* @__PURE__ */ jsx(DialogContent, { className: "sm:max-w-xs", showCloseButton: false, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 py-4", children: [
|
|
2965
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-8 text-primary animate-spin" }),
|
|
2966
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2967
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "text-base", children: "Connecting..." }),
|
|
2968
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "text-sm mt-1", children: "Preparing Google authentication" })
|
|
2969
|
+
] }),
|
|
2970
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: cancelOAuth, children: "Cancel" })
|
|
2971
|
+
] }) }) })
|
|
2776
2972
|
] });
|
|
2777
2973
|
};
|
|
2778
|
-
var DriveSidebar = () => {
|
|
2974
|
+
var DriveSidebar = ({ className }) => {
|
|
2779
2975
|
const [sheetOpen, setSheetOpen] = useState(false);
|
|
2780
|
-
return /* @__PURE__ */ jsxs(
|
|
2781
|
-
/* @__PURE__ */ jsx(
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
"aria-label": "Open menu",
|
|
2789
|
-
children: /* @__PURE__ */ jsx(Menu, { className: "h-5 w-5" })
|
|
2790
|
-
}
|
|
2791
|
-
) }),
|
|
2792
|
-
/* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "w-70 sm:w-80 p-0", hideCloseButton: true, children: [
|
|
2793
|
-
/* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Navigation Menu" }),
|
|
2794
|
-
/* @__PURE__ */ jsx(SheetDescription, { className: "sr-only", children: "Storage accounts and navigation" }),
|
|
2795
|
-
/* @__PURE__ */ jsx(SidebarContent, { onNavigate: () => setSheetOpen(false) })
|
|
2796
|
-
] })
|
|
2797
|
-
] }) }),
|
|
2798
|
-
/* @__PURE__ */ jsx("div", { className: "hidden lg:flex w-full h-full", children: /* @__PURE__ */ jsx(SidebarContent, {}) })
|
|
2799
|
-
] });
|
|
2976
|
+
return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsxs(Sheet, { open: sheetOpen, onOpenChange: setSheetOpen, children: [
|
|
2977
|
+
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "size-9", "aria-label": "Open menu", children: /* @__PURE__ */ jsx(Menu, { className: "size-5" }) }) }),
|
|
2978
|
+
/* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "w-70 sm:w-80 p-0", hideCloseButton: true, children: [
|
|
2979
|
+
/* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Navigation Menu" }),
|
|
2980
|
+
/* @__PURE__ */ jsx(SheetDescription, { className: "sr-only", children: "Storage accounts and navigation" }),
|
|
2981
|
+
/* @__PURE__ */ jsx(SidebarContent, { onNavigate: () => setSheetOpen(false) })
|
|
2982
|
+
] })
|
|
2983
|
+
] }) });
|
|
2800
2984
|
};
|
|
2801
|
-
var SortableItem2 = (
|
|
2985
|
+
var SortableItem2 = (props) => {
|
|
2986
|
+
const { id, children, disabled, isDragOverTarget } = props;
|
|
2802
2987
|
const {
|
|
2803
2988
|
attributes,
|
|
2804
2989
|
listeners,
|
|
@@ -3016,13 +3201,14 @@ var DriveExplorer = (props) => {
|
|
|
3016
3201
|
}
|
|
3017
3202
|
return null;
|
|
3018
3203
|
})();
|
|
3019
|
-
return /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection: closestCenter, onDragStart: handleDragStart, onDragOver: handleDragOver, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full w-full overflow-hidden bg-background/50 dark:bg-background/30", children: [
|
|
3020
|
-
/* @__PURE__ */
|
|
3021
|
-
|
|
3022
|
-
/* @__PURE__ */ jsx(
|
|
3204
|
+
return /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection: closestCenter, onDragStart: handleDragStart, onDragOver: handleDragOver, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full w-full overflow-hidden bg-background/50 dark:bg-background/30 relative", children: [
|
|
3205
|
+
/* @__PURE__ */ jsx(DriveContentProgress, {}),
|
|
3206
|
+
/* @__PURE__ */ jsxs("div", { className: "h-12 px-3 sm:px-4 border-b bg-background/95 dark:bg-background/80 backdrop-blur-sm flex items-center gap-3", children: [
|
|
3207
|
+
/* @__PURE__ */ jsx(DriveSidebar, { className: "lg:hidden" }),
|
|
3208
|
+
/* @__PURE__ */ jsx(DrivePathBar, { className: "hidden lg:flex flex-1" }),
|
|
3023
3209
|
/* @__PURE__ */ jsx(DriveUpload, { compact: true, accept: mimeFilter })
|
|
3024
3210
|
] }),
|
|
3025
|
-
/* @__PURE__ */ jsx("div", { className: "lg:hidden px-3 py-2 border-b bg-background/95 dark:bg-background/80 backdrop-blur-sm
|
|
3211
|
+
/* @__PURE__ */ jsx("div", { className: "lg:hidden px-3 py-2 border-b bg-background/95 dark:bg-background/80 backdrop-blur-sm", children: /* @__PURE__ */ jsx(DrivePathBar, {}) }),
|
|
3026
3212
|
stateContent || /* @__PURE__ */ jsxs(ContextMenu, { children: [
|
|
3027
3213
|
/* @__PURE__ */ jsx(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: cn("flex-1 overflow-y-auto min-h-0 container mx-auto p-2 sm:p-3 md:p-4", className), children: [
|
|
3028
3214
|
/* @__PURE__ */ jsx("div", { className: "space-y-4 sm:space-y-6 pb-8 sm:pb-12", children: Object.entries(groupedItems).map(([groupName, groupItems]) => /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
@@ -3178,6 +3364,26 @@ var DriveExplorer = (props) => {
|
|
|
3178
3364
|
] }) });
|
|
3179
3365
|
};
|
|
3180
3366
|
|
|
3181
|
-
|
|
3367
|
+
// src/client/index.ts
|
|
3368
|
+
if (typeof document !== "undefined") {
|
|
3369
|
+
const STYLE_ID = "next-drive-styles";
|
|
3370
|
+
if (!document.getElementById(STYLE_ID)) {
|
|
3371
|
+
const style = document.createElement("style");
|
|
3372
|
+
style.id = STYLE_ID;
|
|
3373
|
+
style.textContent = `
|
|
3374
|
+
@keyframes indeterminate {
|
|
3375
|
+
0% { transform: translateX(-100%); }
|
|
3376
|
+
50% { transform: translateX(200%); }
|
|
3377
|
+
100% { transform: translateX(-100%); }
|
|
3378
|
+
}
|
|
3379
|
+
.animate-indeterminate {
|
|
3380
|
+
animation: indeterminate 1.5s ease-in-out infinite;
|
|
3381
|
+
}
|
|
3382
|
+
`;
|
|
3383
|
+
document.head.appendChild(style);
|
|
3384
|
+
}
|
|
3385
|
+
}
|
|
3386
|
+
|
|
3387
|
+
export { DriveContentProgress, DriveDndProvider, DriveExplorer, DriveFileChooser, DriveFileGrid, DriveHeader, DrivePathBar, DriveProvider, DriveSidebar, DriveStorageIndicator, DriveUpload, useDrive, useDriveDnd, useUpload };
|
|
3182
3388
|
//# sourceMappingURL=index.js.map
|
|
3183
3389
|
//# sourceMappingURL=index.js.map
|