diff --git a/packages/upup/src/frontend/components/MainBox.tsx b/packages/upup/src/frontend/components/MainBox.tsx
index 65ab111f..f84cbf7b 100644
--- a/packages/upup/src/frontend/components/MainBox.tsx
+++ b/packages/upup/src/frontend/components/MainBox.tsx
@@ -10,11 +10,15 @@ import AdapterView from './AdapterView'
import FileList from './FileList'
import MyAnimatePresence from './shared/MyAnimatePresence'
import ShouldRender from './shared/ShouldRender'
+import WarningAlert from './WarningAlert'
+
export default function MainBox() {
const {
files,
activeAdapter,
isAddingMore,
+ warningMessage,
+ clearWarning,
props: { dark },
} = useRootContext()
const {
@@ -50,6 +54,13 @@ export default function MainBox() {
onDragLeave={handleDragLeave}
onDrop={handleDrop}
>
+
+
+
diff --git a/packages/upup/src/frontend/components/WarningAlert.tsx b/packages/upup/src/frontend/components/WarningAlert.tsx
new file mode 100644
index 00000000..f3a5dab5
--- /dev/null
+++ b/packages/upup/src/frontend/components/WarningAlert.tsx
@@ -0,0 +1,59 @@
+import { motion } from 'framer-motion'
+import React from 'react'
+import { TbAlertCircle, TbX } from 'react-icons/tb'
+import { cn } from '../lib/tailwind'
+
+interface WarningAlertProps {
+ message: string
+ onClose: () => void
+ dark?: boolean
+}
+
+export default function WarningAlert({
+ message,
+ onClose,
+ dark = false,
+}: WarningAlertProps) {
+ return (
+
+
+
+ {message}
+
+
+
+ )
+}
diff --git a/packages/upup/src/frontend/context/RootContext.ts b/packages/upup/src/frontend/context/RootContext.ts
index b5afd38e..b87690ea 100644
--- a/packages/upup/src/frontend/context/RootContext.ts
+++ b/packages/upup/src/frontend/context/RootContext.ts
@@ -81,6 +81,8 @@ export interface IRootContext {
googleDriveConfigs?: GoogleDriveConfigs
dropboxConfigs?: DropboxConfigs
upload: ContextUpload
+ warningMessage: string
+ clearWarning: () => void
props: ContextProps
}
diff --git a/packages/upup/src/frontend/hooks/useRootProvider.ts b/packages/upup/src/frontend/hooks/useRootProvider.ts
index 1cfa7bbf..8cbcbb8d 100644
--- a/packages/upup/src/frontend/hooks/useRootProvider.ts
+++ b/packages/upup/src/frontend/hooks/useRootProvider.ts
@@ -77,6 +77,7 @@ export default function useRootProvider({
{} as FilesProgressMap,
)
const [uploadError, setUploadError] = useState('')
+ const [warningMessage, setWarningMessage] = useState('')
// Keep a ref to selectedFilesMap for unmount cleanup
const selectedFilesMapRef = useRef(selectedFilesMap)
@@ -118,10 +119,16 @@ export default function useRootProvider({
const onWarn = useCallback(
(message: string) => {
+ setWarningMessage(message)
if (warningHandler) warningHandler(message)
},
[warningHandler],
)
+
+ const clearWarning = useCallback(() => {
+ setWarningMessage('')
+ }, [])
+
function isFileWithParamsArray(
files: File[] | FileWithParams[],
): files is FileWithParams[] {
@@ -166,11 +173,22 @@ export default function useRootProvider({
// Collect only the files that are actually accepted and added in this batch.
const addedThisBatch: FileWithParams[] = []
+ const totalSelectedFiles = newFiles.length
for (const file of newFiles) {
// Respect the limit strictly; stop when capacity is reached.
if (newFilesMap.size >= limit) {
- onWarn('Allowed limit has been surpassed!')
+ const remainingCount =
+ totalSelectedFiles - addedThisBatch.length
+ onWarn(
+ `You selected ${totalSelectedFiles} file${
+ totalSelectedFiles > 1 ? 's' : ''
+ }. Only ${limit} ${
+ limit > 1 ? 'were' : 'was'
+ } added. ${remainingCount} file${
+ remainingCount > 1 ? 's' : ''
+ } ignored.`,
+ )
break
}
@@ -278,6 +296,7 @@ export default function useRootProvider({
if (!selectedFilesMap.size && !dynamicFiles) return
setUploadStatus(UploadStatus.ONGOING)
setUploadError('')
+ clearWarning()
const sendEvent = !dynamicFiles
const selectedFiles = dynamicFiles
? dynamicFiles
@@ -363,6 +382,7 @@ export default function useRootProvider({
onError,
onFileUploadProgress,
onFilesUploadProgress,
+ clearWarning,
],
)
const handleCancel = useCallback(() => {
@@ -404,6 +424,8 @@ export default function useRootProvider({
setUploadStatus,
uploadError,
},
+ warningMessage,
+ clearWarning,
props: {
mini,
dark,