import { XCircle, Plus, Share, X, File } from "@styled-icons/boxicons-regular"; import styled from "styled-components"; import { Text } from "preact-i18n"; import { useEffect, useState } from "preact/hooks"; import { determineFileSize } from "../../../../lib/fileSize"; import { CAN_UPLOAD_AT_ONCE, UploadState } from "../MessageBox"; 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: 0.8em; overflow: hidden; max-width: 180px; text-align: center; white-space: nowrap; text-overflow: ellipsis; color: var(--secondary-foreground); } span.size { font-size: 0.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; width: 100%; 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" && ( )} ); }