@ai-matrx/media 0.4.4 → 0.4.5
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/CHANGELOG.md +18 -0
- package/dist/core.cjs.map +1 -1
- package/dist/core.js.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +164 -78
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +162 -76
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -465,11 +465,11 @@ function FileIcon2({
|
|
|
465
465
|
|
|
466
466
|
// src/react/inline-media-ref.tsx
|
|
467
467
|
import {
|
|
468
|
-
useCallback as
|
|
469
|
-
useEffect as
|
|
468
|
+
useCallback as useCallback3,
|
|
469
|
+
useEffect as useEffect5,
|
|
470
470
|
useMemo as useMemo2,
|
|
471
|
-
useRef as
|
|
472
|
-
useState as
|
|
471
|
+
useRef as useRef4,
|
|
472
|
+
useState as useState4
|
|
473
473
|
} from "react";
|
|
474
474
|
|
|
475
475
|
// src/core/context.ts
|
|
@@ -620,8 +620,83 @@ function useMediaBlob(ref) {
|
|
|
620
620
|
};
|
|
621
621
|
}
|
|
622
622
|
|
|
623
|
+
// src/core/use-media-blob-load-recovery.ts
|
|
624
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
625
|
+
function useMediaBlobLoadRecovery(ref, source, options) {
|
|
626
|
+
const client = useMediaClient();
|
|
627
|
+
const capture = useMediaFailureCapture();
|
|
628
|
+
const refKey = stableRefKey(ref);
|
|
629
|
+
const [failed, setFailed] = useState2(false);
|
|
630
|
+
const attemptRef = useRef2(0);
|
|
631
|
+
const recoveryInFlightRef = useRef2(false);
|
|
632
|
+
const onRetry = options.onRetry;
|
|
633
|
+
const onTerminal = options.onTerminal;
|
|
634
|
+
useEffect2(() => {
|
|
635
|
+
attemptRef.current = 0;
|
|
636
|
+
recoveryInFlightRef.current = false;
|
|
637
|
+
setFailed(false);
|
|
638
|
+
}, [refKey]);
|
|
639
|
+
useEffect2(() => {
|
|
640
|
+
recoveryInFlightRef.current = false;
|
|
641
|
+
}, [source]);
|
|
642
|
+
const finishTerminal = useCallback2(
|
|
643
|
+
(event, attempt, message) => {
|
|
644
|
+
setFailed(true);
|
|
645
|
+
capture({
|
|
646
|
+
phase: "element-load",
|
|
647
|
+
mediaRef: failureMediaIdentity(ref ?? null, source),
|
|
648
|
+
terminal: true,
|
|
649
|
+
retryOutcome: attempt > 1 ? "retried" : "not-attempted",
|
|
650
|
+
message
|
|
651
|
+
});
|
|
652
|
+
onTerminal?.(event);
|
|
653
|
+
},
|
|
654
|
+
[capture, onTerminal, ref, source]
|
|
655
|
+
);
|
|
656
|
+
const onLoadError = useCallback2(
|
|
657
|
+
(event) => {
|
|
658
|
+
if (recoveryInFlightRef.current || !source) return;
|
|
659
|
+
recoveryInFlightRef.current = true;
|
|
660
|
+
attemptRef.current += 1;
|
|
661
|
+
const attempt = attemptRef.current;
|
|
662
|
+
const recover = client.recoverBlobLoadError;
|
|
663
|
+
if (!ref || !recover) {
|
|
664
|
+
finishTerminal(
|
|
665
|
+
event,
|
|
666
|
+
attempt,
|
|
667
|
+
"blob-backed media element failed to load and the client exposes no object-URL recovery policy"
|
|
668
|
+
);
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
recover(ref, attempt).then(
|
|
672
|
+
(verdict) => {
|
|
673
|
+
if (verdict === "retry") {
|
|
674
|
+
setFailed(false);
|
|
675
|
+
onRetry();
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
finishTerminal(
|
|
679
|
+
event,
|
|
680
|
+
attempt,
|
|
681
|
+
attempt > 1 ? "blob-backed media element failed after the client-approved re-read" : "blob-backed media recovery was declined on the first attempt"
|
|
682
|
+
);
|
|
683
|
+
},
|
|
684
|
+
(err) => {
|
|
685
|
+
finishTerminal(
|
|
686
|
+
event,
|
|
687
|
+
attempt,
|
|
688
|
+
`blob-backed media recovery failed: ${err instanceof Error ? err.message : String(err ?? "unknown error")}`
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
);
|
|
692
|
+
},
|
|
693
|
+
[client, finishTerminal, onRetry, ref, source]
|
|
694
|
+
);
|
|
695
|
+
return { onLoadError, failed };
|
|
696
|
+
}
|
|
697
|
+
|
|
623
698
|
// src/core/use-media-load-recovery.ts
|
|
624
|
-
import { useEffect as
|
|
699
|
+
import { useEffect as useEffect3, useLayoutEffect, useRef as useRef3, useState as useState3 } from "react";
|
|
625
700
|
|
|
626
701
|
// src/types.ts
|
|
627
702
|
function mintDurableSrc(url) {
|
|
@@ -639,10 +714,10 @@ function useMediaLoadRecovery(src, options) {
|
|
|
639
714
|
const recoverable = options?.recoverable !== false;
|
|
640
715
|
const onTerminal = options?.onTerminal;
|
|
641
716
|
const failureRef = options?.failureRef;
|
|
642
|
-
const [result, setResult] =
|
|
643
|
-
const attemptRef =
|
|
644
|
-
const recoveryInFlightRef =
|
|
645
|
-
|
|
717
|
+
const [result, setResult] = useState3({ source: src, retryKey: 0, failed: false });
|
|
718
|
+
const attemptRef = useRef3(0);
|
|
719
|
+
const recoveryInFlightRef = useRef3(false);
|
|
720
|
+
useEffect3(() => {
|
|
646
721
|
attemptRef.current = 0;
|
|
647
722
|
recoveryInFlightRef.current = false;
|
|
648
723
|
}, [src]);
|
|
@@ -720,7 +795,7 @@ function useMediaLoadRecovery(src, options) {
|
|
|
720
795
|
}
|
|
721
796
|
|
|
722
797
|
// src/core/use-media-resolution.ts
|
|
723
|
-
import { useEffect as
|
|
798
|
+
import { useEffect as useEffect4, useMemo } from "react";
|
|
724
799
|
function useMediaResolution(ref) {
|
|
725
800
|
const client = useMediaClient();
|
|
726
801
|
const capture = useMediaFailureCapture();
|
|
@@ -755,7 +830,7 @@ function useMediaResolution(ref) {
|
|
|
755
830
|
};
|
|
756
831
|
}
|
|
757
832
|
}, [client, refKey]);
|
|
758
|
-
|
|
833
|
+
useEffect4(() => {
|
|
759
834
|
if (state.status !== "unavailable") return;
|
|
760
835
|
capture({
|
|
761
836
|
phase: "resolve",
|
|
@@ -810,7 +885,7 @@ function prettifyUrl(url) {
|
|
|
810
885
|
}
|
|
811
886
|
var INERT_PLAYBACK = {
|
|
812
887
|
useMediaElementSink(forward) {
|
|
813
|
-
return
|
|
888
|
+
return useCallback3(
|
|
814
889
|
(node) => {
|
|
815
890
|
if (!forward) return;
|
|
816
891
|
if (typeof forward === "function") forward(node);
|
|
@@ -861,7 +936,7 @@ function InformativeErrorFallback({
|
|
|
861
936
|
}) {
|
|
862
937
|
const capture = useMediaFailureCapture();
|
|
863
938
|
const identity = failureMediaIdentity(mediaRef ?? null, url);
|
|
864
|
-
|
|
939
|
+
useEffect5(() => {
|
|
865
940
|
capture({
|
|
866
941
|
phase: failurePhase,
|
|
867
942
|
mediaRef: identity,
|
|
@@ -925,10 +1000,10 @@ function InformativeErrorPanel({
|
|
|
925
1000
|
icon,
|
|
926
1001
|
tooltip
|
|
927
1002
|
}) {
|
|
928
|
-
const [copied, setCopied] =
|
|
1003
|
+
const [copied, setCopied] = useState4(false);
|
|
929
1004
|
const isFill = dimensions === "fill";
|
|
930
1005
|
const { host, tail } = prettifyUrl(url);
|
|
931
|
-
const handleCopy =
|
|
1006
|
+
const handleCopy = useCallback3(
|
|
932
1007
|
(event) => {
|
|
933
1008
|
event.stopPropagation();
|
|
934
1009
|
event.preventDefault();
|
|
@@ -1045,16 +1120,25 @@ function InlineMediaRef({
|
|
|
1045
1120
|
);
|
|
1046
1121
|
const blob = useMediaBlob(needsBlob ? mediaRef : null);
|
|
1047
1122
|
const url = needsBlob ? blob.url : resolution?.src ?? null;
|
|
1123
|
+
const terminalCallback = (event) => onError?.(
|
|
1124
|
+
event
|
|
1125
|
+
);
|
|
1048
1126
|
const recovery = useMediaLoadRecovery(url, {
|
|
1049
|
-
recoverable:
|
|
1127
|
+
recoverable: resolution?.recoverable !== false,
|
|
1050
1128
|
failureRef: mediaRef,
|
|
1051
|
-
onTerminal:
|
|
1052
|
-
event
|
|
1053
|
-
)
|
|
1129
|
+
onTerminal: terminalCallback
|
|
1054
1130
|
});
|
|
1131
|
+
const blobRecovery = useMediaBlobLoadRecovery(
|
|
1132
|
+
needsBlob ? mediaRef : null,
|
|
1133
|
+
needsBlob ? url : null,
|
|
1134
|
+
{
|
|
1135
|
+
onRetry: blob.retry,
|
|
1136
|
+
onTerminal: terminalCallback
|
|
1137
|
+
}
|
|
1138
|
+
);
|
|
1055
1139
|
const playback = ports.playbackSession ?? INERT_PLAYBACK;
|
|
1056
|
-
const sessionElRef =
|
|
1057
|
-
const [isMediaPlaying, setIsMediaPlaying] =
|
|
1140
|
+
const sessionElRef = useRef4(null);
|
|
1141
|
+
const [isMediaPlaying, setIsMediaPlaying] = useState4(false);
|
|
1058
1142
|
const portSinkRef = playback.useMediaElementSink(
|
|
1059
1143
|
mediaElementRef
|
|
1060
1144
|
);
|
|
@@ -1085,8 +1169,10 @@ function InlineMediaRef({
|
|
|
1085
1169
|
const mediaResolutionError = status === "unavailable" ? reason ?? "unknown" : blob.error ?? null;
|
|
1086
1170
|
const dimensions = resolveDimensions(size);
|
|
1087
1171
|
const isFill = dimensions === "fill";
|
|
1088
|
-
const
|
|
1089
|
-
const
|
|
1172
|
+
const activeRecovery = needsBlob ? blobRecovery : recovery;
|
|
1173
|
+
const retryKey = needsBlob ? 0 : recovery.retryKey;
|
|
1174
|
+
const hasLoadError = activeRecovery.failed;
|
|
1175
|
+
const handleLoadError = activeRecovery.onLoadError;
|
|
1090
1176
|
const defaultIcon = elementType === "video" ? /* @__PURE__ */ jsx3(FileVideoIcon, { className: "h-1/2 w-1/2" }) : elementType === "audio" ? /* @__PURE__ */ jsx3(FileAudioIcon, { className: "h-1/2 w-1/2" }) : mediaRef ? /* @__PURE__ */ jsx3(ImageIcon, { className: "h-1/2 w-1/2" }) : /* @__PURE__ */ jsx3(FileIcon, { className: "h-1/2 w-1/2" });
|
|
1091
1177
|
const unresolvedDisplayUrl = mediaRef && typeof mediaRef === "object" && mediaRef.file_id ? `file:${mediaRef.file_id}` : "unresolved-media";
|
|
1092
1178
|
if (!url) {
|
|
@@ -1222,7 +1308,7 @@ function InlineMediaRef({
|
|
|
1222
1308
|
...mediaSessionEvents,
|
|
1223
1309
|
...interactiveProps
|
|
1224
1310
|
},
|
|
1225
|
-
|
|
1311
|
+
retryKey
|
|
1226
1312
|
);
|
|
1227
1313
|
}
|
|
1228
1314
|
if (elementType === "audio") {
|
|
@@ -1243,7 +1329,7 @@ function InlineMediaRef({
|
|
|
1243
1329
|
crossOrigin,
|
|
1244
1330
|
...interactiveProps
|
|
1245
1331
|
},
|
|
1246
|
-
|
|
1332
|
+
retryKey
|
|
1247
1333
|
);
|
|
1248
1334
|
}
|
|
1249
1335
|
const needsPlainImg = !!onLoad || !!mediaElementRef || !!crossOrigin;
|
|
@@ -1261,7 +1347,7 @@ function InlineMediaRef({
|
|
|
1261
1347
|
onError: handleLoadError,
|
|
1262
1348
|
...interactiveProps
|
|
1263
1349
|
},
|
|
1264
|
-
|
|
1350
|
+
retryKey
|
|
1265
1351
|
);
|
|
1266
1352
|
}
|
|
1267
1353
|
return /* @__PURE__ */ jsx3(
|
|
@@ -1277,12 +1363,12 @@ function InlineMediaRef({
|
|
|
1277
1363
|
crossOrigin,
|
|
1278
1364
|
...interactiveProps
|
|
1279
1365
|
},
|
|
1280
|
-
|
|
1366
|
+
retryKey
|
|
1281
1367
|
);
|
|
1282
1368
|
}
|
|
1283
1369
|
|
|
1284
1370
|
// src/react/media-thumbnail.tsx
|
|
1285
|
-
import { useEffect as
|
|
1371
|
+
import { useEffect as useEffect6, useRef as useRef5 } from "react";
|
|
1286
1372
|
|
|
1287
1373
|
// src/core/use-thumbnail-source.ts
|
|
1288
1374
|
import { useMemo as useMemo3 } from "react";
|
|
@@ -1440,8 +1526,8 @@ function VideoPosterThumb({
|
|
|
1440
1526
|
recoverable,
|
|
1441
1527
|
failureRef: mediaRef
|
|
1442
1528
|
});
|
|
1443
|
-
const ref =
|
|
1444
|
-
|
|
1529
|
+
const ref = useRef5(null);
|
|
1530
|
+
useEffect6(() => {
|
|
1445
1531
|
const v = ref.current;
|
|
1446
1532
|
if (!v) return void 0;
|
|
1447
1533
|
const onMeta = () => {
|
|
@@ -1471,11 +1557,11 @@ function VideoPosterThumb({
|
|
|
1471
1557
|
|
|
1472
1558
|
// src/react/use-media-dropzone.ts
|
|
1473
1559
|
import {
|
|
1474
|
-
useCallback as
|
|
1475
|
-
useEffect as
|
|
1560
|
+
useCallback as useCallback4,
|
|
1561
|
+
useEffect as useEffect7,
|
|
1476
1562
|
useMemo as useMemo4,
|
|
1477
|
-
useRef as
|
|
1478
|
-
useState as
|
|
1563
|
+
useRef as useRef6,
|
|
1564
|
+
useState as useState5
|
|
1479
1565
|
} from "react";
|
|
1480
1566
|
function matchesAccept(file, accept) {
|
|
1481
1567
|
if (!accept || accept.length === 0) return true;
|
|
@@ -1500,16 +1586,16 @@ function useMediaDropzone(options) {
|
|
|
1500
1586
|
disabled = false,
|
|
1501
1587
|
multiple = true
|
|
1502
1588
|
} = options;
|
|
1503
|
-
const [isDragActive, setIsDragActive] =
|
|
1504
|
-
const [pasteHighlight, setPasteHighlight] =
|
|
1505
|
-
const dragDepth =
|
|
1506
|
-
const inputRef =
|
|
1507
|
-
const onFilesRef =
|
|
1589
|
+
const [isDragActive, setIsDragActive] = useState5(false);
|
|
1590
|
+
const [pasteHighlight, setPasteHighlight] = useState5(false);
|
|
1591
|
+
const dragDepth = useRef6(0);
|
|
1592
|
+
const inputRef = useRef6(null);
|
|
1593
|
+
const onFilesRef = useRef6(onFiles);
|
|
1508
1594
|
onFilesRef.current = onFiles;
|
|
1509
|
-
const onRejectedRef =
|
|
1595
|
+
const onRejectedRef = useRef6(onRejected);
|
|
1510
1596
|
onRejectedRef.current = onRejected;
|
|
1511
1597
|
const acceptKey = accept?.join(",") ?? "";
|
|
1512
|
-
const filterFiles =
|
|
1598
|
+
const filterFiles = useCallback4(
|
|
1513
1599
|
(files) => {
|
|
1514
1600
|
const accepted = [];
|
|
1515
1601
|
const rejected = [];
|
|
@@ -1527,23 +1613,23 @@ function useMediaDropzone(options) {
|
|
|
1527
1613
|
},
|
|
1528
1614
|
[acceptKey, maxSize]
|
|
1529
1615
|
);
|
|
1530
|
-
const emit =
|
|
1616
|
+
const emit = useCallback4(
|
|
1531
1617
|
(files) => {
|
|
1532
1618
|
const accepted = filterFiles(files);
|
|
1533
1619
|
if (accepted.length) onFilesRef.current(accepted);
|
|
1534
1620
|
},
|
|
1535
1621
|
[filterFiles]
|
|
1536
1622
|
);
|
|
1537
|
-
const openPicker =
|
|
1623
|
+
const openPicker = useCallback4(() => {
|
|
1538
1624
|
if (!disabled) inputRef.current?.click();
|
|
1539
1625
|
}, [disabled]);
|
|
1540
|
-
|
|
1626
|
+
useEffect7(() => {
|
|
1541
1627
|
if (!pickerEventName || typeof window === "undefined") return void 0;
|
|
1542
1628
|
const handler = () => openPicker();
|
|
1543
1629
|
window.addEventListener(pickerEventName, handler);
|
|
1544
1630
|
return () => window.removeEventListener(pickerEventName, handler);
|
|
1545
1631
|
}, [openPicker, pickerEventName]);
|
|
1546
|
-
|
|
1632
|
+
useEffect7(() => {
|
|
1547
1633
|
if (!enablePaste || disabled || typeof window === "undefined") {
|
|
1548
1634
|
return void 0;
|
|
1549
1635
|
}
|
|
@@ -1569,7 +1655,7 @@ function useMediaDropzone(options) {
|
|
|
1569
1655
|
window.addEventListener("paste", handler);
|
|
1570
1656
|
return () => window.removeEventListener("paste", handler);
|
|
1571
1657
|
}, [enablePaste, disabled, emit]);
|
|
1572
|
-
const getRootProps =
|
|
1658
|
+
const getRootProps = useCallback4(
|
|
1573
1659
|
() => ({
|
|
1574
1660
|
onDragEnter: (event) => {
|
|
1575
1661
|
if (disabled) return;
|
|
@@ -1602,7 +1688,7 @@ function useMediaDropzone(options) {
|
|
|
1602
1688
|
() => acceptKey.length ? acceptKey : void 0,
|
|
1603
1689
|
[acceptKey]
|
|
1604
1690
|
);
|
|
1605
|
-
const getInputProps =
|
|
1691
|
+
const getInputProps = useCallback4(
|
|
1606
1692
|
() => ({
|
|
1607
1693
|
ref: (node) => {
|
|
1608
1694
|
inputRef.current = node;
|
|
@@ -1624,20 +1710,20 @@ function useMediaDropzone(options) {
|
|
|
1624
1710
|
}
|
|
1625
1711
|
|
|
1626
1712
|
// src/react/file-upload-dropzone.tsx
|
|
1627
|
-
import { useCallback as
|
|
1713
|
+
import { useCallback as useCallback6 } from "react";
|
|
1628
1714
|
|
|
1629
1715
|
// src/core/use-media-upload.ts
|
|
1630
|
-
import { useCallback as
|
|
1716
|
+
import { useCallback as useCallback5, useRef as useRef7, useState as useState6 } from "react";
|
|
1631
1717
|
var entrySeq = 0;
|
|
1632
1718
|
function useMediaUpload() {
|
|
1633
1719
|
const client = useMediaClient();
|
|
1634
|
-
const [uploading, setUploading] =
|
|
1635
|
-
const [progress, setProgress] =
|
|
1636
|
-
const [result, setResult] =
|
|
1637
|
-
const [error, setError] =
|
|
1638
|
-
const [entries, setEntries] =
|
|
1639
|
-
const activeCount =
|
|
1640
|
-
const patchEntry =
|
|
1720
|
+
const [uploading, setUploading] = useState6(false);
|
|
1721
|
+
const [progress, setProgress] = useState6(null);
|
|
1722
|
+
const [result, setResult] = useState6(null);
|
|
1723
|
+
const [error, setError] = useState6(null);
|
|
1724
|
+
const [entries, setEntries] = useState6([]);
|
|
1725
|
+
const activeCount = useRef7(0);
|
|
1726
|
+
const patchEntry = useCallback5(
|
|
1641
1727
|
(id, patch) => {
|
|
1642
1728
|
setEntries(
|
|
1643
1729
|
(current) => current.map((e) => e.id === id ? { ...e, ...patch } : e)
|
|
@@ -1645,7 +1731,7 @@ function useMediaUpload() {
|
|
|
1645
1731
|
},
|
|
1646
1732
|
[]
|
|
1647
1733
|
);
|
|
1648
|
-
const upload =
|
|
1734
|
+
const upload = useCallback5(
|
|
1649
1735
|
async (file, opts = {}) => {
|
|
1650
1736
|
const id = `up-${++entrySeq}`;
|
|
1651
1737
|
const fileName = opts.fileName ?? (file instanceof File ? file.name : "file");
|
|
@@ -1699,7 +1785,7 @@ function useMediaUpload() {
|
|
|
1699
1785
|
},
|
|
1700
1786
|
[client, patchEntry]
|
|
1701
1787
|
);
|
|
1702
|
-
const uploadMany =
|
|
1788
|
+
const uploadMany = useCallback5(
|
|
1703
1789
|
async (files, opts = {}) => {
|
|
1704
1790
|
if (client.uploadMany) {
|
|
1705
1791
|
activeCount.current += 1;
|
|
@@ -1728,10 +1814,10 @@ function useMediaUpload() {
|
|
|
1728
1814
|
},
|
|
1729
1815
|
[client, upload]
|
|
1730
1816
|
);
|
|
1731
|
-
const clearEntry =
|
|
1817
|
+
const clearEntry = useCallback5((id) => {
|
|
1732
1818
|
setEntries((current) => current.filter((e) => e.id !== id));
|
|
1733
1819
|
}, []);
|
|
1734
|
-
const reset =
|
|
1820
|
+
const reset = useCallback5(() => {
|
|
1735
1821
|
setResult(null);
|
|
1736
1822
|
setError(null);
|
|
1737
1823
|
setProgress(null);
|
|
@@ -1751,7 +1837,7 @@ function useMediaUpload() {
|
|
|
1751
1837
|
}
|
|
1752
1838
|
|
|
1753
1839
|
// src/react/upload-progress-list.tsx
|
|
1754
|
-
import { memo, useEffect as
|
|
1840
|
+
import { memo, useEffect as useEffect8, useRef as useRef8, useState as useState7 } from "react";
|
|
1755
1841
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1756
1842
|
var AUTO_DISMISS_MS = 1e4;
|
|
1757
1843
|
function formatFileSize(bytes) {
|
|
@@ -1772,16 +1858,16 @@ function UploadProgressListImpl({
|
|
|
1772
1858
|
onOpenFile,
|
|
1773
1859
|
className
|
|
1774
1860
|
}) {
|
|
1775
|
-
const [hovered, setHovered] =
|
|
1861
|
+
const [hovered, setHovered] = useState7(false);
|
|
1776
1862
|
const activeCount = uploads.filter((u) => u.status === "uploading").length;
|
|
1777
1863
|
const successCount = uploads.filter((u) => u.status === "success").length;
|
|
1778
1864
|
const errorCount = uploads.filter((u) => u.status === "error").length;
|
|
1779
|
-
const timersRef =
|
|
1865
|
+
const timersRef = useRef8(
|
|
1780
1866
|
/* @__PURE__ */ new Map()
|
|
1781
1867
|
);
|
|
1782
|
-
const onDismissRef =
|
|
1868
|
+
const onDismissRef = useRef8(onDismiss);
|
|
1783
1869
|
onDismissRef.current = onDismiss;
|
|
1784
|
-
|
|
1870
|
+
useEffect8(() => {
|
|
1785
1871
|
const timers = timersRef.current;
|
|
1786
1872
|
if (hovered) {
|
|
1787
1873
|
timers.forEach((t) => clearTimeout(t));
|
|
@@ -1809,7 +1895,7 @@ function UploadProgressListImpl({
|
|
|
1809
1895
|
}
|
|
1810
1896
|
}
|
|
1811
1897
|
}, [uploads, hovered]);
|
|
1812
|
-
|
|
1898
|
+
useEffect8(() => {
|
|
1813
1899
|
const timers = timersRef.current;
|
|
1814
1900
|
return () => {
|
|
1815
1901
|
timers.forEach((t) => clearTimeout(t));
|
|
@@ -1941,7 +2027,7 @@ function FileUploadDropzone({
|
|
|
1941
2027
|
pickerEventName
|
|
1942
2028
|
}) {
|
|
1943
2029
|
const { uploadMany, entries, clearEntry } = useMediaUpload();
|
|
1944
|
-
const handleUpload =
|
|
2030
|
+
const handleUpload = useCallback6(
|
|
1945
2031
|
async (files) => {
|
|
1946
2032
|
if (!files.length) return;
|
|
1947
2033
|
try {
|
|
@@ -2048,22 +2134,22 @@ function FileUploadDropzone({
|
|
|
2048
2134
|
}
|
|
2049
2135
|
|
|
2050
2136
|
// src/react/media-action-toolbar.tsx
|
|
2051
|
-
import { useState as
|
|
2137
|
+
import { useState as useState9 } from "react";
|
|
2052
2138
|
|
|
2053
2139
|
// src/core/use-media-actions.ts
|
|
2054
|
-
import { useCallback as
|
|
2140
|
+
import { useCallback as useCallback7, useMemo as useMemo5, useState as useState8 } from "react";
|
|
2055
2141
|
function useMediaActions(ref, options = {}) {
|
|
2056
2142
|
const ports = useMediaHostPorts();
|
|
2057
2143
|
const { resolution } = useMediaResolution(ref);
|
|
2058
|
-
const [busy, setBusy] =
|
|
2059
|
-
const [lastError, setLastError] =
|
|
2144
|
+
const [busy, setBusy] = useState8(null);
|
|
2145
|
+
const [lastError, setLastError] = useState8(null);
|
|
2060
2146
|
const actions = ports.actions;
|
|
2061
2147
|
const { fileName, alt } = options;
|
|
2062
2148
|
const context = useMemo5(() => {
|
|
2063
2149
|
if (!ref) return null;
|
|
2064
2150
|
return { ref, resolution, fileName, alt };
|
|
2065
2151
|
}, [ref, resolution, fileName, alt]);
|
|
2066
|
-
const isAvailable =
|
|
2152
|
+
const isAvailable = useCallback7(
|
|
2067
2153
|
(kind) => {
|
|
2068
2154
|
if (!context || !actions) return false;
|
|
2069
2155
|
if (kind === "share") return Boolean(actions.share || actions.SharePopover);
|
|
@@ -2071,7 +2157,7 @@ function useMediaActions(ref, options = {}) {
|
|
|
2071
2157
|
},
|
|
2072
2158
|
[context, actions]
|
|
2073
2159
|
);
|
|
2074
|
-
const run =
|
|
2160
|
+
const run = useCallback7(
|
|
2075
2161
|
async (kind) => {
|
|
2076
2162
|
if (!context || !actions) return;
|
|
2077
2163
|
const handler = actions[kind];
|
|
@@ -2120,7 +2206,7 @@ function MediaActionToolbar({
|
|
|
2120
2206
|
buttonClassName
|
|
2121
2207
|
}) {
|
|
2122
2208
|
const state = useMediaActions(mediaRef, { fileName, alt });
|
|
2123
|
-
const [shareOpen, setShareOpen] =
|
|
2209
|
+
const [shareOpen, setShareOpen] = useState9(false);
|
|
2124
2210
|
const SharePopover = state.SharePopover;
|
|
2125
2211
|
const visible = hideUnavailable ? actions.filter((kind) => state.isAvailable(kind)) : actions;
|
|
2126
2212
|
if (visible.length === 0) return null;
|
|
@@ -2177,7 +2263,7 @@ function MediaActionToolbar({
|
|
|
2177
2263
|
}
|
|
2178
2264
|
|
|
2179
2265
|
// src/react/media-lightbox.tsx
|
|
2180
|
-
import { useEffect as
|
|
2266
|
+
import { useEffect as useEffect9 } from "react";
|
|
2181
2267
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2182
2268
|
function MediaLightbox({
|
|
2183
2269
|
open,
|
|
@@ -2195,7 +2281,7 @@ function MediaLightbox({
|
|
|
2195
2281
|
headerExtra,
|
|
2196
2282
|
className
|
|
2197
2283
|
}) {
|
|
2198
|
-
|
|
2284
|
+
useEffect9(() => {
|
|
2199
2285
|
if (!open || typeof window === "undefined") return void 0;
|
|
2200
2286
|
const handler = (event) => {
|
|
2201
2287
|
if (event.key === "Escape") {
|