@plugable-io/react 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +34 -4
- package/dist/index.mjs +35 -5
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -92,8 +92,9 @@ interface FileImageProps {
|
|
|
92
92
|
style?: CSSProperties;
|
|
93
93
|
onLoad?: () => void;
|
|
94
94
|
onError?: (error: Error) => void;
|
|
95
|
+
onRefetchNeeded?: () => Promise<void>;
|
|
95
96
|
}
|
|
96
|
-
declare function FileImage({ file, width, height, objectFit, borderRadius, alt, className, style, onLoad, onError, }: FileImageProps): react_jsx_runtime.JSX.Element;
|
|
97
|
+
declare function FileImage({ file, width, height, objectFit, borderRadius, alt, className, style, onLoad, onError, onRefetchNeeded, }: FileImageProps): react_jsx_runtime.JSX.Element;
|
|
97
98
|
declare function clearImageCache(): void;
|
|
98
99
|
|
|
99
100
|
interface FilePreviewProps {
|
|
@@ -106,7 +107,7 @@ interface FilePreviewProps {
|
|
|
106
107
|
showExtension?: boolean;
|
|
107
108
|
renderNonImage?: (file: FileObject) => React.ReactNode;
|
|
108
109
|
}
|
|
109
|
-
declare function FilePreview({ file, width, height, className, style, objectFit, showExtension, renderNonImage, }: FilePreviewProps): react_jsx_runtime.JSX.Element;
|
|
110
|
+
declare function FilePreview({ file: initialFile, width, height, className, style, objectFit, showExtension, renderNonImage, }: FilePreviewProps): react_jsx_runtime.JSX.Element;
|
|
110
111
|
|
|
111
112
|
interface UseFilesOptions {
|
|
112
113
|
metadata?: Record<string, any>;
|
package/dist/index.d.ts
CHANGED
|
@@ -92,8 +92,9 @@ interface FileImageProps {
|
|
|
92
92
|
style?: CSSProperties;
|
|
93
93
|
onLoad?: () => void;
|
|
94
94
|
onError?: (error: Error) => void;
|
|
95
|
+
onRefetchNeeded?: () => Promise<void>;
|
|
95
96
|
}
|
|
96
|
-
declare function FileImage({ file, width, height, objectFit, borderRadius, alt, className, style, onLoad, onError, }: FileImageProps): react_jsx_runtime.JSX.Element;
|
|
97
|
+
declare function FileImage({ file, width, height, objectFit, borderRadius, alt, className, style, onLoad, onError, onRefetchNeeded, }: FileImageProps): react_jsx_runtime.JSX.Element;
|
|
97
98
|
declare function clearImageCache(): void;
|
|
98
99
|
|
|
99
100
|
interface FilePreviewProps {
|
|
@@ -106,7 +107,7 @@ interface FilePreviewProps {
|
|
|
106
107
|
showExtension?: boolean;
|
|
107
108
|
renderNonImage?: (file: FileObject) => React.ReactNode;
|
|
108
109
|
}
|
|
109
|
-
declare function FilePreview({ file, width, height, className, style, objectFit, showExtension, renderNonImage, }: FilePreviewProps): react_jsx_runtime.JSX.Element;
|
|
110
|
+
declare function FilePreview({ file: initialFile, width, height, className, style, objectFit, showExtension, renderNonImage, }: FilePreviewProps): react_jsx_runtime.JSX.Element;
|
|
110
111
|
|
|
111
112
|
interface UseFilesOptions {
|
|
112
113
|
metadata?: Record<string, any>;
|
package/dist/index.js
CHANGED
|
@@ -579,11 +579,13 @@ function FileImage({
|
|
|
579
579
|
className,
|
|
580
580
|
style,
|
|
581
581
|
onLoad,
|
|
582
|
-
onError
|
|
582
|
+
onError,
|
|
583
|
+
onRefetchNeeded
|
|
583
584
|
}) {
|
|
584
585
|
const [imageSrc, setImageSrc] = (0, import_react4.useState)(null);
|
|
585
586
|
const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
|
|
586
587
|
const [error, setError] = (0, import_react4.useState)(null);
|
|
588
|
+
const refetchAttemptedRef = (0, import_react4.useRef)(null);
|
|
587
589
|
(0, import_react4.useEffect)(() => {
|
|
588
590
|
let isMounted = true;
|
|
589
591
|
let objectUrl = null;
|
|
@@ -606,6 +608,13 @@ function FileImage({
|
|
|
606
608
|
}
|
|
607
609
|
});
|
|
608
610
|
if (!response.ok) {
|
|
611
|
+
const downloadUrlKey = `${file.id}-${file.download_url}`;
|
|
612
|
+
if (response.status === 403 && onRefetchNeeded && refetchAttemptedRef.current !== downloadUrlKey) {
|
|
613
|
+
refetchAttemptedRef.current = downloadUrlKey;
|
|
614
|
+
imageCache.delete(cacheKey);
|
|
615
|
+
await onRefetchNeeded();
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
609
618
|
throw new Error(`Failed to fetch image: ${response.statusText}`);
|
|
610
619
|
}
|
|
611
620
|
const blob = await response.blob();
|
|
@@ -614,6 +623,7 @@ function FileImage({
|
|
|
614
623
|
if (isMounted) {
|
|
615
624
|
setImageSrc(objectUrl);
|
|
616
625
|
setIsLoading(false);
|
|
626
|
+
refetchAttemptedRef.current = null;
|
|
617
627
|
}
|
|
618
628
|
} else {
|
|
619
629
|
throw new Error("No download URL available for file");
|
|
@@ -632,7 +642,7 @@ function FileImage({
|
|
|
632
642
|
return () => {
|
|
633
643
|
isMounted = false;
|
|
634
644
|
};
|
|
635
|
-
}, [file.id, file.checksum, file.download_url, onError]);
|
|
645
|
+
}, [file.id, file.checksum, file.download_url, onError, onRefetchNeeded]);
|
|
636
646
|
const handleLoad = () => {
|
|
637
647
|
setIsLoading(false);
|
|
638
648
|
onLoad?.();
|
|
@@ -722,9 +732,10 @@ function clearImageCache() {
|
|
|
722
732
|
}
|
|
723
733
|
|
|
724
734
|
// src/components/FilePreview.tsx
|
|
735
|
+
var import_react5 = require("react");
|
|
725
736
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
726
737
|
function FilePreview({
|
|
727
|
-
file,
|
|
738
|
+
file: initialFile,
|
|
728
739
|
width = 80,
|
|
729
740
|
height = 80,
|
|
730
741
|
className,
|
|
@@ -733,6 +744,24 @@ function FilePreview({
|
|
|
733
744
|
showExtension = true,
|
|
734
745
|
renderNonImage
|
|
735
746
|
}) {
|
|
747
|
+
const { client } = usePlugable();
|
|
748
|
+
const [file, setFile] = (0, import_react5.useState)(initialFile);
|
|
749
|
+
const [isRefetching, setIsRefetching] = (0, import_react5.useState)(false);
|
|
750
|
+
(0, import_react5.useEffect)(() => {
|
|
751
|
+
setFile(initialFile);
|
|
752
|
+
}, [initialFile.id, initialFile.download_url]);
|
|
753
|
+
const handleRefetch = (0, import_react5.useCallback)(async () => {
|
|
754
|
+
if (isRefetching) return;
|
|
755
|
+
try {
|
|
756
|
+
setIsRefetching(true);
|
|
757
|
+
const refreshedFile = await client.get(file.id);
|
|
758
|
+
setFile(refreshedFile);
|
|
759
|
+
} catch (err) {
|
|
760
|
+
console.error("Failed to refetch file:", err);
|
|
761
|
+
} finally {
|
|
762
|
+
setIsRefetching(false);
|
|
763
|
+
}
|
|
764
|
+
}, [file.id, client]);
|
|
736
765
|
const isImage = file.content_type.startsWith("image/");
|
|
737
766
|
const containerStyle = {
|
|
738
767
|
width,
|
|
@@ -756,7 +785,8 @@ function FilePreview({
|
|
|
756
785
|
objectFit,
|
|
757
786
|
className,
|
|
758
787
|
style,
|
|
759
|
-
borderRadius: 4
|
|
788
|
+
borderRadius: 4,
|
|
789
|
+
onRefetchNeeded: handleRefetch
|
|
760
790
|
}
|
|
761
791
|
);
|
|
762
792
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -523,7 +523,7 @@ function FileList({
|
|
|
523
523
|
}
|
|
524
524
|
|
|
525
525
|
// src/components/FileImage.tsx
|
|
526
|
-
import { useEffect as useEffect2, useState as useState4 } from "react";
|
|
526
|
+
import { useEffect as useEffect2, useState as useState4, useRef as useRef3 } from "react";
|
|
527
527
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
528
528
|
var imageCache = /* @__PURE__ */ new Map();
|
|
529
529
|
function FileImage({
|
|
@@ -536,11 +536,13 @@ function FileImage({
|
|
|
536
536
|
className,
|
|
537
537
|
style,
|
|
538
538
|
onLoad,
|
|
539
|
-
onError
|
|
539
|
+
onError,
|
|
540
|
+
onRefetchNeeded
|
|
540
541
|
}) {
|
|
541
542
|
const [imageSrc, setImageSrc] = useState4(null);
|
|
542
543
|
const [isLoading, setIsLoading] = useState4(true);
|
|
543
544
|
const [error, setError] = useState4(null);
|
|
545
|
+
const refetchAttemptedRef = useRef3(null);
|
|
544
546
|
useEffect2(() => {
|
|
545
547
|
let isMounted = true;
|
|
546
548
|
let objectUrl = null;
|
|
@@ -563,6 +565,13 @@ function FileImage({
|
|
|
563
565
|
}
|
|
564
566
|
});
|
|
565
567
|
if (!response.ok) {
|
|
568
|
+
const downloadUrlKey = `${file.id}-${file.download_url}`;
|
|
569
|
+
if (response.status === 403 && onRefetchNeeded && refetchAttemptedRef.current !== downloadUrlKey) {
|
|
570
|
+
refetchAttemptedRef.current = downloadUrlKey;
|
|
571
|
+
imageCache.delete(cacheKey);
|
|
572
|
+
await onRefetchNeeded();
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
566
575
|
throw new Error(`Failed to fetch image: ${response.statusText}`);
|
|
567
576
|
}
|
|
568
577
|
const blob = await response.blob();
|
|
@@ -571,6 +580,7 @@ function FileImage({
|
|
|
571
580
|
if (isMounted) {
|
|
572
581
|
setImageSrc(objectUrl);
|
|
573
582
|
setIsLoading(false);
|
|
583
|
+
refetchAttemptedRef.current = null;
|
|
574
584
|
}
|
|
575
585
|
} else {
|
|
576
586
|
throw new Error("No download URL available for file");
|
|
@@ -589,7 +599,7 @@ function FileImage({
|
|
|
589
599
|
return () => {
|
|
590
600
|
isMounted = false;
|
|
591
601
|
};
|
|
592
|
-
}, [file.id, file.checksum, file.download_url, onError]);
|
|
602
|
+
}, [file.id, file.checksum, file.download_url, onError, onRefetchNeeded]);
|
|
593
603
|
const handleLoad = () => {
|
|
594
604
|
setIsLoading(false);
|
|
595
605
|
onLoad?.();
|
|
@@ -679,9 +689,10 @@ function clearImageCache() {
|
|
|
679
689
|
}
|
|
680
690
|
|
|
681
691
|
// src/components/FilePreview.tsx
|
|
692
|
+
import { useState as useState5, useCallback as useCallback4, useEffect as useEffect3 } from "react";
|
|
682
693
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
683
694
|
function FilePreview({
|
|
684
|
-
file,
|
|
695
|
+
file: initialFile,
|
|
685
696
|
width = 80,
|
|
686
697
|
height = 80,
|
|
687
698
|
className,
|
|
@@ -690,6 +701,24 @@ function FilePreview({
|
|
|
690
701
|
showExtension = true,
|
|
691
702
|
renderNonImage
|
|
692
703
|
}) {
|
|
704
|
+
const { client } = usePlugable();
|
|
705
|
+
const [file, setFile] = useState5(initialFile);
|
|
706
|
+
const [isRefetching, setIsRefetching] = useState5(false);
|
|
707
|
+
useEffect3(() => {
|
|
708
|
+
setFile(initialFile);
|
|
709
|
+
}, [initialFile.id, initialFile.download_url]);
|
|
710
|
+
const handleRefetch = useCallback4(async () => {
|
|
711
|
+
if (isRefetching) return;
|
|
712
|
+
try {
|
|
713
|
+
setIsRefetching(true);
|
|
714
|
+
const refreshedFile = await client.get(file.id);
|
|
715
|
+
setFile(refreshedFile);
|
|
716
|
+
} catch (err) {
|
|
717
|
+
console.error("Failed to refetch file:", err);
|
|
718
|
+
} finally {
|
|
719
|
+
setIsRefetching(false);
|
|
720
|
+
}
|
|
721
|
+
}, [file.id, client]);
|
|
693
722
|
const isImage = file.content_type.startsWith("image/");
|
|
694
723
|
const containerStyle = {
|
|
695
724
|
width,
|
|
@@ -713,7 +742,8 @@ function FilePreview({
|
|
|
713
742
|
objectFit,
|
|
714
743
|
className,
|
|
715
744
|
style,
|
|
716
|
-
borderRadius: 4
|
|
745
|
+
borderRadius: 4,
|
|
746
|
+
onRefetchNeeded: handleRefetch
|
|
717
747
|
}
|
|
718
748
|
);
|
|
719
749
|
}
|