import { FC, ReactNode } from 'react' import { PktIcon } from '..' import { OperationButton, TransferError, TransferInProgress } from './Subcomponents' import { TFileAndTransfer, TFileId, TItemRenderer, TQueueItemOperation, TTransferItemInProgress } from './types' const isImageFile = (item: TFileAndTransfer): boolean => { if (item.file.type?.startsWith('image/')) return true return /\.(jpe?g|png|gif|webp|heic|heif|bmp|svg)$/i.test(item.file.name || '') } type TProgressState = 'in-progress' | 'error' | 'idle' export const getProgressState = (progress: TFileAndTransfer['progress']): TProgressState => { if (typeof progress === 'number') return 'in-progress' if (progress === 'error') return 'error' return 'idle' } // ============================================ // OperationActions - Renders action buttons for a file // ============================================ interface IOperationActions { operations: TQueueItemOperation[] activatedOperation?: TQueueItemOperation onActivate: (fileId: TFileId, operation: TQueueItemOperation) => void transferItem: TFileAndTransfer } export const OperationActions: FC = ({ operations, activatedOperation, onActivate, transferItem, }) => (
{operations .filter((op) => !activatedOperation || op.symbol !== activatedOperation.symbol) .map((operation) => ( ))}
) // ============================================ // OperationContents - Renders operation content areas // ============================================ interface IOperationContents { operations: TQueueItemOperation[] activatedOperation?: TQueueItemOperation onActivate: (fileId: TFileId, operation: TQueueItemOperation) => void transferItem: TFileAndTransfer } export const OperationContents: FC = ({ operations, activatedOperation, onActivate, transferItem, }) => ( <> {operations .filter((op) => op.renderContent) .map((operation) => (
{operation.renderContent!( transferItem, () => onActivate(transferItem.fileId, operation), activatedOperation?.symbol === operation.symbol, )}
))} ) // ============================================ // IdleStateContent - Renders content for idle/done state // ============================================ interface IIdleStateContent { transferItem: TFileAndTransfer activatedOperation?: TQueueItemOperation operations: TQueueItemOperation[] ItemRenderer: TItemRenderer onActivate: (fileId: TFileId, operation: TQueueItemOperation) => void onClose: (fileId: TFileId) => void onPreviewClick?: () => void } export const IdleStateContent: FC = ({ transferItem, activatedOperation, operations, ItemRenderer, onActivate, onClose, onPreviewClick, }) => { const closeUI = () => onClose(transferItem.fileId) // When any operation UI is active (rename inline or comments extended), hide all action buttons. const hasOperationUIActive = activatedOperation?.renderInlineUI || activatedOperation?.renderExtendedUI const visibleOperations = hasOperationUIActive ? [] : operations return ( <> {activatedOperation?.renderInlineUI ? ( <>
{activatedOperation.renderInlineUI(transferItem, closeUI)}
) : ( )} {visibleOperations.length > 0 && ( )} {activatedOperation?.renderExtendedUI && (
{activatedOperation.renderExtendedUI(transferItem, closeUI)}
)} ) } // ============================================ // QueueItemContent - Main content renderer based on state // ============================================ interface IQueueItemContent { transferItem: TFileAndTransfer activatedOperation?: TQueueItemOperation operations: TQueueItemOperation[] ItemRenderer: TItemRenderer enableImagePreview: boolean onActivate: (fileId: TFileId, operation: TQueueItemOperation) => void onClose: (fileId: TFileId) => void onCancelTransfer: (fileId: string) => void onOpenPreview: (fileId: TFileId) => void } export const QueueItemContent: FC = ({ transferItem, activatedOperation, operations, ItemRenderer, enableImagePreview, onActivate, onClose, onCancelTransfer, onOpenPreview, }) => { const state = getProgressState(transferItem.progress) const isPreviewable = enableImagePreview && transferItem.progress === 'done' && isImageFile(transferItem) switch (state) { case 'in-progress': return ( onCancelTransfer(transferItem.fileId)} /> ) case 'error': return onCancelTransfer(transferItem.fileId)} /> case 'idle': return ( onOpenPreview(transferItem.fileId) : undefined} /> ) } }