import { Text } from "preact-i18n"; import styled from "styled-components"; import { CAN_UPLOAD_AT_ONCE, UploadState } from "../MessageBox"; import { useEffect, useState } from 'preact/hooks'; import { determineFileSize } from '../../../../lib/fileSize'; import { XCircle, Plus, Share, X, FileText } from "@styled-icons/feather"; interface Props { state: UploadState, addFile: () => void, removeFile: (index: number) => void } const Container = styled.div` gap: 4px; padding: 8px; display: flex; user-select: none; flex-direction: column; background: var(--message-box); `; const Carousel = styled.div` gap: 8px; display: flex; overflow-x: scroll; flex-direction: row; `; const Entry = styled.div` display: flex; flex-direction: column; &.fade { opacity: 0.4; } span.fn { margin: auto; font-size: .8em; overflow: hidden; max-width: 180px; text-align: center; white-space: nowrap; text-overflow: ellipsis; color: var(--secondary-foreground); } span.size { font-size: .6em; color: var(--tertiary-foreground); text-align: center; } `; const Description = styled.div` gap: 4px; display: flex; font-size: 0.9em; align-items: center; color: var(--secondary-foreground); `; const Divider = styled.div` width: 4px; height: 130px; flex-shrink: 0; border-radius: 4px; background: var(--tertiary-background); `; const EmptyEntry = styled.div` width: 100px; height: 100px; display: grid; flex-shrink: 0; cursor: pointer; border-radius: 4px; place-items: center; background: var(--primary-background); transition: 0.1s ease background-color; &:hover { background: var(--secondary-background); } `; const PreviewBox = styled.div` display: grid; grid-template: "main" 100px / minmax(100px, 1fr); justify-items: center; background: var(--primary-background); overflow: hidden; cursor: pointer; border-radius: 4px; .icon, .overlay { grid-area: main } .icon { height: 100px; margin-bottom: 4px; object-fit: contain; } .overlay { display: grid; align-items: center; justify-content: center; width: 100%; height: 100%; opacity: 0; visibility: hidden; transition: 0.1s ease opacity; } &:hover { .overlay { visibility: visible; opacity: 1; background-color: rgba(0, 0, 0, 0.8); } } ` function FileEntry({ file, remove, index }: { file: File, remove?: () => void, index: number }) { if (!file.type.startsWith('image/')) return ( = CAN_UPLOAD_AT_ONCE ? 'fade' : ''}>
{file.name} {determineFileSize(file.size)}
); const [ url, setURL ] = useState(''); useEffect(() => { let url: string = URL.createObjectURL(file); setURL(url); return () => URL.revokeObjectURL(url); }, [ file ]); return ( = CAN_UPLOAD_AT_ONCE ? 'fade' : ''}> {file.name}
{file.name} {determineFileSize(file.size)}
) } export default function FilePreview({ state, addFile, removeFile }: Props) { if (state.type === 'none') return null; return ( { state.files.map((file, index) => <> { index === CAN_UPLOAD_AT_ONCE && } removeFile(index) : undefined} /> ) } { state.type === 'attached' && } { state.type === 'uploading' && ({state.percent}%) } { state.type === 'sending' && Sending... } { state.type === 'failed' && } ); }