@moontra/moonui-pro 2.11.1 → 2.11.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/dist/index.mjs +99 -6
- package/package.json +1 -1
- package/src/components/file-upload/index.tsx +130 -7
package/dist/index.mjs
CHANGED
|
@@ -58976,6 +58976,10 @@ var MoonUIFileUploadPro = t__default.forwardRef(
|
|
|
58976
58976
|
onPreview,
|
|
58977
58977
|
onBulkSelect,
|
|
58978
58978
|
customValidation,
|
|
58979
|
+
serviceConfig,
|
|
58980
|
+
imageResize,
|
|
58981
|
+
endpoint,
|
|
58982
|
+
headers,
|
|
58979
58983
|
...props
|
|
58980
58984
|
}, ref) => {
|
|
58981
58985
|
const { hasProAccess, isLoading } = useSubscription();
|
|
@@ -59067,6 +59071,90 @@ var MoonUIFileUploadPro = t__default.forwardRef(
|
|
|
59067
59071
|
}
|
|
59068
59072
|
return metadata;
|
|
59069
59073
|
}, [duplicateCheck]);
|
|
59074
|
+
const uploadToService = useCallback(async (fileItem) => {
|
|
59075
|
+
if (!serviceConfig)
|
|
59076
|
+
return null;
|
|
59077
|
+
const { file } = fileItem;
|
|
59078
|
+
switch (serviceConfig.type) {
|
|
59079
|
+
case "aws-s3":
|
|
59080
|
+
if (uploadStrategy === "presigned" && endpoint) {
|
|
59081
|
+
const response = await fetch(endpoint, {
|
|
59082
|
+
method: "PUT",
|
|
59083
|
+
body: file,
|
|
59084
|
+
headers: {
|
|
59085
|
+
"Content-Type": file.type,
|
|
59086
|
+
...headers
|
|
59087
|
+
}
|
|
59088
|
+
});
|
|
59089
|
+
return response.ok ? { url: response.url } : null;
|
|
59090
|
+
}
|
|
59091
|
+
break;
|
|
59092
|
+
case "cloudinary":
|
|
59093
|
+
if (serviceConfig.cloudinaryConfig) {
|
|
59094
|
+
const { cloudName, uploadPreset } = serviceConfig.cloudinaryConfig;
|
|
59095
|
+
const formData = new FormData();
|
|
59096
|
+
formData.append("file", file);
|
|
59097
|
+
formData.append("upload_preset", uploadPreset);
|
|
59098
|
+
const response = await fetch(
|
|
59099
|
+
`https://api.cloudinary.com/v1_1/${cloudName}/auto/upload`,
|
|
59100
|
+
{
|
|
59101
|
+
method: "POST",
|
|
59102
|
+
body: formData
|
|
59103
|
+
}
|
|
59104
|
+
);
|
|
59105
|
+
return response.json();
|
|
59106
|
+
}
|
|
59107
|
+
break;
|
|
59108
|
+
}
|
|
59109
|
+
return null;
|
|
59110
|
+
}, [serviceConfig, uploadStrategy, endpoint, headers]);
|
|
59111
|
+
const resizeImage = useCallback(async (file) => {
|
|
59112
|
+
if (!imageResize || !file.type.startsWith("image/"))
|
|
59113
|
+
return file;
|
|
59114
|
+
const { maxWidth, maxHeight, quality } = imageResize;
|
|
59115
|
+
return new Promise((resolve) => {
|
|
59116
|
+
const img = new Image();
|
|
59117
|
+
const reader = new FileReader();
|
|
59118
|
+
reader.onload = (e) => {
|
|
59119
|
+
img.src = e.target?.result;
|
|
59120
|
+
img.onload = () => {
|
|
59121
|
+
const canvas = document.createElement("canvas");
|
|
59122
|
+
const ctx = canvas.getContext("2d");
|
|
59123
|
+
let width = img.width;
|
|
59124
|
+
let height = img.height;
|
|
59125
|
+
if (width > maxWidth || height > maxHeight) {
|
|
59126
|
+
const aspectRatio = width / height;
|
|
59127
|
+
if (width > height) {
|
|
59128
|
+
width = maxWidth;
|
|
59129
|
+
height = maxWidth / aspectRatio;
|
|
59130
|
+
} else {
|
|
59131
|
+
height = maxHeight;
|
|
59132
|
+
width = maxHeight * aspectRatio;
|
|
59133
|
+
}
|
|
59134
|
+
}
|
|
59135
|
+
canvas.width = width;
|
|
59136
|
+
canvas.height = height;
|
|
59137
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
59138
|
+
canvas.toBlob(
|
|
59139
|
+
(blob) => {
|
|
59140
|
+
if (blob) {
|
|
59141
|
+
const resizedFile = new window.File([blob], file.name, {
|
|
59142
|
+
type: file.type,
|
|
59143
|
+
lastModified: Date.now()
|
|
59144
|
+
});
|
|
59145
|
+
resolve(resizedFile);
|
|
59146
|
+
} else {
|
|
59147
|
+
resolve(file);
|
|
59148
|
+
}
|
|
59149
|
+
},
|
|
59150
|
+
file.type,
|
|
59151
|
+
quality
|
|
59152
|
+
);
|
|
59153
|
+
};
|
|
59154
|
+
};
|
|
59155
|
+
reader.readAsDataURL(file);
|
|
59156
|
+
});
|
|
59157
|
+
}, [imageResize]);
|
|
59070
59158
|
const uploadFileChunked = useCallback(async (fileItem) => {
|
|
59071
59159
|
const { file } = fileItem;
|
|
59072
59160
|
const chunks = [];
|
|
@@ -59092,7 +59180,10 @@ var MoonUIFileUploadPro = t__default.forwardRef(
|
|
|
59092
59180
|
if (abortController.signal.aborted) {
|
|
59093
59181
|
throw new Error("Upload cancelled");
|
|
59094
59182
|
}
|
|
59095
|
-
|
|
59183
|
+
const serviceResult = await uploadToService(fileItem);
|
|
59184
|
+
if (!serviceResult) {
|
|
59185
|
+
await new Promise((resolve) => setTimeout(resolve, 100 + Math.random() * 200));
|
|
59186
|
+
}
|
|
59096
59187
|
uploadedBytes += chunk.end - chunk.start;
|
|
59097
59188
|
const progress = Math.round(uploadedBytes / file.size * 100);
|
|
59098
59189
|
const elapsedTime = (Date.now() - startTime) / 1e3;
|
|
@@ -59163,14 +59254,15 @@ var MoonUIFileUploadPro = t__default.forwardRef(
|
|
|
59163
59254
|
const newFileItems = [];
|
|
59164
59255
|
for (const file of validFiles) {
|
|
59165
59256
|
const id = `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
59166
|
-
const
|
|
59167
|
-
const
|
|
59257
|
+
const processedFile = await resizeImage(file);
|
|
59258
|
+
const preview = await createPreview(processedFile);
|
|
59259
|
+
const metadata = await createMetadata(processedFile);
|
|
59168
59260
|
newFileItems.push({
|
|
59169
59261
|
id,
|
|
59170
|
-
file,
|
|
59262
|
+
file: processedFile,
|
|
59171
59263
|
status: "pending",
|
|
59172
59264
|
progress: 0,
|
|
59173
|
-
totalBytes:
|
|
59265
|
+
totalBytes: processedFile.size,
|
|
59174
59266
|
preview,
|
|
59175
59267
|
metadata
|
|
59176
59268
|
});
|
|
@@ -59196,7 +59288,8 @@ var MoonUIFileUploadPro = t__default.forwardRef(
|
|
|
59196
59288
|
createPreview,
|
|
59197
59289
|
createMetadata,
|
|
59198
59290
|
onUpload,
|
|
59199
|
-
uploadFileChunked
|
|
59291
|
+
uploadFileChunked,
|
|
59292
|
+
resizeImage
|
|
59200
59293
|
]);
|
|
59201
59294
|
const handleDrop = useCallback((e) => {
|
|
59202
59295
|
e.preventDefault();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moontra/moonui-pro",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.2",
|
|
4
4
|
"description": "Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -477,6 +477,10 @@ export const MoonUIFileUploadPro = React.forwardRef<HTMLDivElement, FileUploadPr
|
|
|
477
477
|
onPreview,
|
|
478
478
|
onBulkSelect,
|
|
479
479
|
customValidation,
|
|
480
|
+
serviceConfig,
|
|
481
|
+
imageResize,
|
|
482
|
+
endpoint,
|
|
483
|
+
headers,
|
|
480
484
|
...props
|
|
481
485
|
}, ref) => {
|
|
482
486
|
|
|
@@ -610,6 +614,115 @@ export const MoonUIFileUploadPro = React.forwardRef<HTMLDivElement, FileUploadPr
|
|
|
610
614
|
return metadata
|
|
611
615
|
}, [duplicateCheck])
|
|
612
616
|
|
|
617
|
+
// Service specific upload handler
|
|
618
|
+
const uploadToService = useCallback(async (fileItem: FileUploadItem): Promise<any> => {
|
|
619
|
+
if (!serviceConfig) return null
|
|
620
|
+
|
|
621
|
+
const { file } = fileItem
|
|
622
|
+
|
|
623
|
+
switch (serviceConfig.type) {
|
|
624
|
+
case 'aws-s3':
|
|
625
|
+
// AWS S3 upload logic
|
|
626
|
+
if (uploadStrategy === 'presigned' && endpoint) {
|
|
627
|
+
const response = await fetch(endpoint, {
|
|
628
|
+
method: 'PUT',
|
|
629
|
+
body: file,
|
|
630
|
+
headers: {
|
|
631
|
+
'Content-Type': file.type,
|
|
632
|
+
...headers
|
|
633
|
+
}
|
|
634
|
+
})
|
|
635
|
+
return response.ok ? { url: response.url } : null
|
|
636
|
+
}
|
|
637
|
+
break
|
|
638
|
+
|
|
639
|
+
case 'cloudinary':
|
|
640
|
+
// Cloudinary upload logic
|
|
641
|
+
if (serviceConfig.cloudinaryConfig) {
|
|
642
|
+
const { cloudName, uploadPreset } = serviceConfig.cloudinaryConfig
|
|
643
|
+
const formData = new FormData()
|
|
644
|
+
formData.append('file', file)
|
|
645
|
+
formData.append('upload_preset', uploadPreset)
|
|
646
|
+
|
|
647
|
+
const response = await fetch(
|
|
648
|
+
`https://api.cloudinary.com/v1_1/${cloudName}/auto/upload`,
|
|
649
|
+
{
|
|
650
|
+
method: 'POST',
|
|
651
|
+
body: formData
|
|
652
|
+
}
|
|
653
|
+
)
|
|
654
|
+
return response.json()
|
|
655
|
+
}
|
|
656
|
+
break
|
|
657
|
+
|
|
658
|
+
case 'firebase':
|
|
659
|
+
// Firebase upload would be handled by the onUpload callback
|
|
660
|
+
// as it requires Firebase SDK integration
|
|
661
|
+
break
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
return null
|
|
665
|
+
}, [serviceConfig, uploadStrategy, endpoint, headers])
|
|
666
|
+
|
|
667
|
+
// Image resize handler
|
|
668
|
+
const resizeImage = useCallback(async (file: File): Promise<File> => {
|
|
669
|
+
if (!imageResize || !file.type.startsWith('image/')) return file
|
|
670
|
+
|
|
671
|
+
const { maxWidth, maxHeight, quality } = imageResize
|
|
672
|
+
|
|
673
|
+
return new Promise((resolve) => {
|
|
674
|
+
const img = new Image()
|
|
675
|
+
const reader = new FileReader()
|
|
676
|
+
|
|
677
|
+
reader.onload = (e) => {
|
|
678
|
+
img.src = e.target?.result as string
|
|
679
|
+
|
|
680
|
+
img.onload = () => {
|
|
681
|
+
const canvas = document.createElement('canvas')
|
|
682
|
+
const ctx = canvas.getContext('2d')!
|
|
683
|
+
|
|
684
|
+
let width = img.width
|
|
685
|
+
let height = img.height
|
|
686
|
+
|
|
687
|
+
// Calculate new dimensions
|
|
688
|
+
if (width > maxWidth || height > maxHeight) {
|
|
689
|
+
const aspectRatio = width / height
|
|
690
|
+
if (width > height) {
|
|
691
|
+
width = maxWidth
|
|
692
|
+
height = maxWidth / aspectRatio
|
|
693
|
+
} else {
|
|
694
|
+
height = maxHeight
|
|
695
|
+
width = maxHeight * aspectRatio
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
canvas.width = width
|
|
700
|
+
canvas.height = height
|
|
701
|
+
ctx.drawImage(img, 0, 0, width, height)
|
|
702
|
+
|
|
703
|
+
canvas.toBlob(
|
|
704
|
+
(blob) => {
|
|
705
|
+
if (blob) {
|
|
706
|
+
// Create a resized file
|
|
707
|
+
const resizedFile = new window.File([blob], file.name, {
|
|
708
|
+
type: file.type,
|
|
709
|
+
lastModified: Date.now()
|
|
710
|
+
})
|
|
711
|
+
resolve(resizedFile)
|
|
712
|
+
} else {
|
|
713
|
+
resolve(file)
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
file.type,
|
|
717
|
+
quality
|
|
718
|
+
)
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
reader.readAsDataURL(file)
|
|
723
|
+
})
|
|
724
|
+
}, [imageResize])
|
|
725
|
+
|
|
613
726
|
// Chunked upload simülasyonu
|
|
614
727
|
const uploadFileChunked = useCallback(async (fileItem: FileUploadItem) => {
|
|
615
728
|
const { file } = fileItem
|
|
@@ -647,8 +760,13 @@ export const MoonUIFileUploadPro = React.forwardRef<HTMLDivElement, FileUploadPr
|
|
|
647
760
|
throw new Error('Upload cancelled')
|
|
648
761
|
}
|
|
649
762
|
|
|
650
|
-
//
|
|
651
|
-
|
|
763
|
+
// Try service-specific upload first
|
|
764
|
+
const serviceResult = await uploadToService(fileItem)
|
|
765
|
+
|
|
766
|
+
if (!serviceResult) {
|
|
767
|
+
// Fallback to chunk upload simulation
|
|
768
|
+
await new Promise(resolve => setTimeout(resolve, 100 + Math.random() * 200))
|
|
769
|
+
}
|
|
652
770
|
|
|
653
771
|
uploadedBytes += (chunk.end - chunk.start)
|
|
654
772
|
const progress = Math.round((uploadedBytes / file.size) * 100)
|
|
@@ -752,15 +870,19 @@ export const MoonUIFileUploadPro = React.forwardRef<HTMLDivElement, FileUploadPr
|
|
|
752
870
|
|
|
753
871
|
for (const file of validFiles) {
|
|
754
872
|
const id = `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`
|
|
755
|
-
|
|
756
|
-
|
|
873
|
+
|
|
874
|
+
// Resize image if needed
|
|
875
|
+
const processedFile = await resizeImage(file)
|
|
876
|
+
|
|
877
|
+
const preview = await createPreview(processedFile)
|
|
878
|
+
const metadata = await createMetadata(processedFile)
|
|
757
879
|
|
|
758
880
|
newFileItems.push({
|
|
759
881
|
id,
|
|
760
|
-
file,
|
|
882
|
+
file: processedFile,
|
|
761
883
|
status: 'pending',
|
|
762
884
|
progress: 0,
|
|
763
|
-
totalBytes:
|
|
885
|
+
totalBytes: processedFile.size,
|
|
764
886
|
preview,
|
|
765
887
|
metadata
|
|
766
888
|
})
|
|
@@ -790,7 +912,8 @@ export const MoonUIFileUploadPro = React.forwardRef<HTMLDivElement, FileUploadPr
|
|
|
790
912
|
createPreview,
|
|
791
913
|
createMetadata,
|
|
792
914
|
onUpload,
|
|
793
|
-
uploadFileChunked
|
|
915
|
+
uploadFileChunked,
|
|
916
|
+
resizeImage
|
|
794
917
|
])
|
|
795
918
|
|
|
796
919
|
// Drag & Drop handlers
|