import * as React from "react"; import * as Constants from "~/common/constants"; import * as Strings from "~/common/strings"; import * as System from "~/components/system"; import * as Store from "~/common/store"; import * as Styles from "~/common/styles"; import * as SVG from "~/common/svg"; import * as Actions from "~/common/actions"; import * as Events from "~/common/custom-events"; import * as FileUtilities from "~/common/file-utilities"; import * as Logging from "~/common/logging"; import { css } from "@emotion/react"; import { DataMeterBar } from "~/components/core/DataMeter"; import { SidebarWarningMessage } from "~/components/core/WarningMessage"; import { FileTypeGroup } from "~/components/core/FileTypeIcon"; const STYLES_FILE_HIDDEN = css` height: 1px; width: 1px; opacity: 0; visibility: hidden; position: fixed; top: -1px; left: -1px; `; const STYLES_FILE_LINE = css` display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 12px 16px; ${"" /* background-color: ${Constants.semantic.bgLight}; */} border: 1px solid ${Constants.system.gray}; border-bottom: none; ${"" /* box-shadow: 0 0 0 1px ${Constants.system.gray} inset; */} :first-child { border-radius: 4px 4px 0 0; } :last-child { border-bottom: 1px solid ${Constants.system.gray}; border-radius: 0 0 4px 4px; } `; const STYLES_FILE_NAME = css` min-width: 10%; width: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size: 0.9rem; font-family: ${Constants.font.medium}; `; const STYLES_LEFT = css` width: 100%; min-width: 10%; display: flex; align-items: center; `; const STYLES_RIGHT = css` flex-shrink: 0; display: flex; align-items: center; `; const STYLES_FILE_STATUS = css` flex-shrink: 0; margin-right: 16px; display: flex; align-items: center; `; const STYLES_BAR_CONTAINER = css` ${"" /* background: ${Constants.semantic.bgLight}; */} border: 1px solid ${Constants.system.gray}; border-radius: 4px; padding: 16px; ${"" /* margin-top: 48px; */} `; const STYLES_PERFORMANCE = css` font-family: ${Constants.font.code}; font-size: 12px; display: block; margin: 0 0 8px 0; `; export default class ModalAddFileToBucket extends React.Component { state = { url: "", slate: this.props.page.id === "NAV_SLATE" && this.props.data?.id ? this.props.data : null, urlError: false, }; componentDidMount = () => { window.addEventListener("keydown", this._handleDocumentKeydown); }; componentWillUnmount = () => { window.removeEventListener("keydown", this._handleDocumentKeydown); }; _handleDocumentKeydown = (e) => { if (e.keyCode === 27) { this.props.onCancel(); e.stopPropagation(); } }; _handleUpload = (e) => { this.props.onUpload({ files: e.target.files, slate: this.state.slate, }); this.props.onCancel(); }; _handleChange = (e) => { this.setState({ [e.target.name]: e.target.value, urlError: false }); }; _handleCancel = (e, key) => { e.preventDefault(); e.stopPropagation(); Events.dispatchCustomEvent({ name: `cancel-${key}` }); //NOTE(martina): so that will cancel if is in the middle of uploading Store.setCancelled(key); //NOTE(martina): so that will cancel if hasn't started uploading yet this.props.onAction({ type: "REGISTER_FILE_CANCELLED", value: key }); //NOTE(martina): so that fileLoading registers it }; _handleUploadLink = () => { if (Strings.isEmpty(this.state.url)) { this.setState({ urlError: true }); return; } try { const url = new URL(this.state.url); } catch (e) { Logging.error(e); this.setState({ urlError: true }); return; } FileUtilities.uploadLink({ url: this.state.url, slate: this.state.slate }); this.props.onCancel(); }; render() { let loaded = 0; let total = 0; if (this.props.fileLoading) { for (let file of Object.values(this.props.fileLoading)) { if (typeof file.loaded === "number" && typeof file.total === "number") { total += file.total; loaded += file.loaded; } } } if (this.props.fileLoading && Object.keys(this.props.fileLoading).length) { return (
Upload Status
{Strings.bytesToSize(loaded)} / {Strings.bytesToSize(total)}
{this.props.fileLoading ? Object.entries(this.props.fileLoading).map((entry) => { let file = entry[1]; return (
{file.failed ? ( ) : file.cancelled ? ( ) : file.loaded === file.total ? ( ) : ( )}
{file.name}
{file.loaded === file.total || file.failed || file.cancelled ? (
) : ( this._handleCancel(e, entry[0])} > )}
); }) : null}
); } else { return (
Drag and drop files or use the button below to save to{" "} {this.props.data ? Strings.getPresentationSlateName(this.props.data) : "Slate"} Please don't upload sensitive information to Slate yet. All uploaded data can currently be accessed by anyone with the link. Private storage is coming soon. Select files
); } } }