From 58588e1b16bf3f3c47c554df465f596e3c65f387 Mon Sep 17 00:00:00 2001 From: stephenOwino <36981339s@gmail.com> Date: Fri, 30 Jan 2026 17:38:33 +0300 Subject: [PATCH 1/3] adedd UI warning alert with file counts when upload limit exceeded --- .../upup/src/frontend/components/MainBox.tsx | 13 +++- .../src/frontend/components/WarningAlert.tsx | 59 +++++++++++++++++++ .../upup/src/frontend/context/RootContext.ts | 4 +- .../src/frontend/hooks/useRootProvider.ts | 19 +++++- 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 packages/upup/src/frontend/components/WarningAlert.tsx diff --git a/packages/upup/src/frontend/components/MainBox.tsx b/packages/upup/src/frontend/components/MainBox.tsx index 65ab111f..55e7756c 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} > + + + @@ -62,4 +73,4 @@ export default function MainBox() { ) -} +} \ No newline at end of file diff --git a/packages/upup/src/frontend/components/WarningAlert.tsx b/packages/upup/src/frontend/components/WarningAlert.tsx new file mode 100644 index 00000000..5fa143e1 --- /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} +

+ +
+ ) +} \ No newline at end of file diff --git a/packages/upup/src/frontend/context/RootContext.ts b/packages/upup/src/frontend/context/RootContext.ts index b5afd38e..48a7c1df 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 } @@ -94,4 +96,4 @@ export function useRootContext() { return contextValue } -export default RootContext +export default RootContext \ No newline at end of file diff --git a/packages/upup/src/frontend/hooks/useRootProvider.ts b/packages/upup/src/frontend/hooks/useRootProvider.ts index 1cfa7bbf..9dcc9c0b 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,15 @@ 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 +289,7 @@ export default function useRootProvider({ if (!selectedFilesMap.size && !dynamicFiles) return setUploadStatus(UploadStatus.ONGOING) setUploadError('') + clearWarning() const sendEvent = !dynamicFiles const selectedFiles = dynamicFiles ? dynamicFiles @@ -363,6 +375,7 @@ export default function useRootProvider({ onError, onFileUploadProgress, onFilesUploadProgress, + clearWarning, ], ) const handleCancel = useCallback(() => { @@ -404,6 +417,8 @@ export default function useRootProvider({ setUploadStatus, uploadError, }, + warningMessage, + clearWarning, props: { mini, dark, @@ -432,4 +447,4 @@ export default function useRootProvider({ classNames, }, } -} +} \ No newline at end of file From f994413cf304c919a302391f900e4bd7e4d53f46 Mon Sep 17 00:00:00 2001 From: stephenOwino <36981339s@gmail.com> Date: Fri, 30 Jan 2026 17:50:48 +0300 Subject: [PATCH 2/3] improve warning alert positioning to prevent text cutoff --- packages/upup/src/frontend/components/WarningAlert.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/upup/src/frontend/components/WarningAlert.tsx b/packages/upup/src/frontend/components/WarningAlert.tsx index 5fa143e1..61173e0e 100644 --- a/packages/upup/src/frontend/components/WarningAlert.tsx +++ b/packages/upup/src/frontend/components/WarningAlert.tsx @@ -20,10 +20,10 @@ export default function WarningAlert({ animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }} className={cn( - 'upup-absolute upup-top-4 upup-left-1/2 upup--translate-x-1/2 upup-z-50', + 'upup-absolute upup-top-4 upup-left-4 upup-right-4 upup-z-50', 'upup-flex upup-items-center upup-gap-2', 'upup-px-4 upup-py-3 upup-rounded-lg upup-shadow-lg', - 'upup-max-w-md upup-w-full', + 'upup-mx-auto upup-max-w-lg', { 'upup-bg-amber-50 upup-border upup-border-amber-200 upup-text-amber-900': !dark, @@ -38,7 +38,7 @@ export default function WarningAlert({ 'upup-text-amber-300': dark, })} /> -

+

{message}

) -} \ No newline at end of file +} diff --git a/packages/upup/src/frontend/context/RootContext.ts b/packages/upup/src/frontend/context/RootContext.ts index 48a7c1df..b87690ea 100644 --- a/packages/upup/src/frontend/context/RootContext.ts +++ b/packages/upup/src/frontend/context/RootContext.ts @@ -96,4 +96,4 @@ export function useRootContext() { return contextValue } -export default RootContext \ No newline at end of file +export default RootContext diff --git a/packages/upup/src/frontend/hooks/useRootProvider.ts b/packages/upup/src/frontend/hooks/useRootProvider.ts index 9dcc9c0b..8cbcbb8d 100644 --- a/packages/upup/src/frontend/hooks/useRootProvider.ts +++ b/packages/upup/src/frontend/hooks/useRootProvider.ts @@ -178,9 +178,16 @@ export default function useRootProvider({ for (const file of newFiles) { // Respect the limit strictly; stop when capacity is reached. if (newFilesMap.size >= limit) { - const remainingCount = totalSelectedFiles - addedThisBatch.length + 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.` + `You selected ${totalSelectedFiles} file${ + totalSelectedFiles > 1 ? 's' : '' + }. Only ${limit} ${ + limit > 1 ? 'were' : 'was' + } added. ${remainingCount} file${ + remainingCount > 1 ? 's' : '' + } ignored.`, ) break } @@ -447,4 +454,4 @@ export default function useRootProvider({ classNames, }, } -} \ No newline at end of file +}