Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/upup/src/frontend/components/MainBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -50,6 +54,13 @@ export default function MainBox() {
onDragLeave={handleDragLeave}
onDrop={handleDrop}
>
<ShouldRender if={!!warningMessage}>
<WarningAlert
message={warningMessage}
onClose={clearWarning}
dark={dark}
/>
</ShouldRender>
<ShouldRender if={!!activeAdapter}>
<AdapterView />
</ShouldRender>
Expand Down
59 changes: 59 additions & 0 deletions packages/upup/src/frontend/components/WarningAlert.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<motion.div
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
className={cn(
'upup-absolute upup-left-4 upup-right-4 upup-top-4 upup-z-50',
'upup-flex upup-items-center upup-gap-2',
'upup-rounded-lg upup-px-4 upup-py-3 upup-shadow-lg',
'upup-mx-auto upup-max-w-lg',
{
'upup-border upup-border-amber-200 upup-bg-amber-50 upup-text-amber-900':
!dark,
'upup-border upup-border-amber-700 upup-bg-amber-900/90 upup-text-amber-100':
dark,
},
)}
>
<TbAlertCircle
className={cn('upup-h-5 upup-w-5 upup-flex-shrink-0', {
'upup-text-amber-600': !dark,
'upup-text-amber-300': dark,
})}
/>
<p className="upup-flex-1 upup-break-words upup-text-sm upup-font-medium">
{message}
</p>
<button
onClick={onClose}
className={cn(
'upup-flex-shrink-0 upup-rounded upup-p-1 upup-transition-colors',
{
'upup-text-amber-600 hover:upup-bg-amber-100': !dark,
'upup-text-amber-300 hover:upup-bg-amber-800': dark,
},
)}
aria-label="Close warning"
>
<TbX className="upup-h-4 upup-w-4" />
</button>
</motion.div>
)
}
2 changes: 2 additions & 0 deletions packages/upup/src/frontend/context/RootContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ export interface IRootContext {
googleDriveConfigs?: GoogleDriveConfigs
dropboxConfigs?: DropboxConfigs
upload: ContextUpload
warningMessage: string
clearWarning: () => void
props: ContextProps
}

Expand Down
24 changes: 23 additions & 1 deletion packages/upup/src/frontend/hooks/useRootProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export default function useRootProvider({
{} as FilesProgressMap,
)
const [uploadError, setUploadError] = useState('')
const [warningMessage, setWarningMessage] = useState<string>('')

// Keep a ref to selectedFilesMap for unmount cleanup
const selectedFilesMapRef = useRef(selectedFilesMap)
Expand Down Expand Up @@ -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[] {
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -363,6 +382,7 @@ export default function useRootProvider({
onError,
onFileUploadProgress,
onFilesUploadProgress,
clearWarning,
],
)
const handleCancel = useCallback(() => {
Expand Down Expand Up @@ -404,6 +424,8 @@ export default function useRootProvider({
setUploadStatus,
uploadError,
},
warningMessage,
clearWarning,
props: {
mini,
dark,
Expand Down
Loading