mirror of
https://github.com/filecoin-project/slate.git
synced 2024-12-25 18:13:10 +03:00
feat(Upload.Popup): add popup indicator when dropping files
This commit is contained in:
parent
f0849b2604
commit
e185c76e5f
@ -50,7 +50,6 @@ const STYLES_APPLICATION_HEADER_BACKGROUND = (theme) => css`
|
||||
z-index: -1;
|
||||
background-color: ${theme.system.white};
|
||||
box-shadow: 0 0 0 1px ${theme.semantic.bgGrayLight};
|
||||
|
||||
@supports ((-webkit-backdrop-filter: blur(75px)) or (backdrop-filter: blur(75px))) {
|
||||
-webkit-backdrop-filter: blur(75px);
|
||||
backdrop-filter: blur(75px);
|
||||
@ -61,7 +60,6 @@ const STYLES_APPLICATION_HEADER_BACKGROUND = (theme) => css`
|
||||
const STYLES_APPLICATION_HEADER = css`
|
||||
${Styles.HORIZONTAL_CONTAINER_CENTERED};
|
||||
padding: 14px 24px;
|
||||
|
||||
@media (max-width: ${Constants.sizes.mobile}px) {
|
||||
padding: 16px 16px 12px;
|
||||
width: 100%;
|
||||
@ -94,7 +92,6 @@ const STYLES_BACKGROUND = css`
|
||||
height: 100vh;
|
||||
background-color: ${Constants.semantic.bgBlurDark};
|
||||
pointer-events: auto;
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 50%;
|
||||
|
@ -25,7 +25,7 @@ import DataMeter from "~/components/core/DataMeter";
|
||||
* UploadModal
|
||||
* -----------------------------------------------------------------------------------------------*/
|
||||
|
||||
const STYLES_MODAL = css`
|
||||
const STYLES_MODAL = (theme) => css`
|
||||
z-index: ${Constants.zindex.uploadModal};
|
||||
top: ${Constants.sizes.header}px;
|
||||
right: 0;
|
||||
@ -33,14 +33,15 @@ const STYLES_MODAL = css`
|
||||
position: fixed;
|
||||
left: 0;
|
||||
padding: 24px 24px 32px;
|
||||
height: calc(100vh - ${Constants.sizes.header}px);
|
||||
height: calc(100vh - ${theme.sizes.header}px);
|
||||
overflow-y: auto;
|
||||
|
||||
background-color: ${Constants.semantic.bgBlurWhiteOP};
|
||||
background-color: ${theme.semantic.bgWhite};
|
||||
|
||||
@supports ((-webkit-backdrop-filter: blur(75px)) or (backdrop-filter: blur(75px))) {
|
||||
-webkit-backdrop-filter: blur(75px);
|
||||
backdrop-filter: blur(75px);
|
||||
background-color: ${theme.semantic.bgBlurWhiteOP};
|
||||
}
|
||||
`;
|
||||
|
||||
|
126
components/core/Upload/Popup.js
Normal file
126
components/core/Upload/Popup.js
Normal file
@ -0,0 +1,126 @@
|
||||
import * as React from "react";
|
||||
import * as System from "~/components/system";
|
||||
import * as Styles from "~/common/styles";
|
||||
import * as Strings from "~/common/strings";
|
||||
import * as FileUtilities from "~/common/file-utilities";
|
||||
|
||||
import { css } from "@emotion/react";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { Show } from "~/components/utility/Show";
|
||||
|
||||
import FilePlaceholder from "~/components/core/ObjectPreview/placeholders/File";
|
||||
import { clamp } from "lodash";
|
||||
import { useEventListener } from "~/common/hooks";
|
||||
|
||||
const STYLES_POPUP = (theme) => css`
|
||||
${Styles.CONTAINER_CENTERED};
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
top: 0px;
|
||||
left: 0;
|
||||
background-color: ${theme.semantic.bgWhite};
|
||||
|
||||
@supports ((-webkit-backdrop-filter: blur(75px)) or (backdrop-filter: blur(75px))) {
|
||||
-webkit-backdrop-filter: blur(75px);
|
||||
backdrop-filter: blur(75px);
|
||||
background-color: ${theme.semantic.bgBlurWhiteOP};
|
||||
}
|
||||
`;
|
||||
|
||||
const STYLES_PLACEHOLDER = css`
|
||||
width: 64px;
|
||||
height: 80px;
|
||||
svg {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export default function Popup() {
|
||||
const DEFAULT_DROPPING_STATE = {
|
||||
isDroppingFiles: false,
|
||||
totalFilesDropped: undefined,
|
||||
};
|
||||
|
||||
const timerRef = React.useRef();
|
||||
|
||||
const [{ isDroppingFiles, totalFilesDropped }, setDroppingState] =
|
||||
React.useState(DEFAULT_DROPPING_STATE);
|
||||
|
||||
const handleDragOver = (e) => {
|
||||
e.preventDefault();
|
||||
// NOTE(amine): Hack to hide the popup if the user drags files outside of the app
|
||||
clearTimeout(timerRef.current);
|
||||
timerRef.current = setTimeout(() => {
|
||||
setDroppingState(DEFAULT_DROPPING_STATE);
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const handleDragEnter = async (e) => {
|
||||
e.preventDefault();
|
||||
const { files } = await FileUtilities.formatDroppedFiles({
|
||||
dataTransfer: e.dataTransfer,
|
||||
});
|
||||
setDroppingState({ totalFilesDropped: files.length || undefined, isDroppingFiles: true });
|
||||
};
|
||||
|
||||
useEventListener("dragenter", handleDragEnter, []);
|
||||
useEventListener("dragover", handleDragOver, []);
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isDroppingFiles ? (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.2, ease: "easeInOut" }}
|
||||
css={STYLES_POPUP}
|
||||
>
|
||||
<DroppedFilesPlaceholder totalFilesDropped={totalFilesDropped} />
|
||||
<div style={{ marginTop: 64 }}>
|
||||
<System.H3 as="p" style={{ textAlign: "center" }}>
|
||||
Dropping {totalFilesDropped}{" "}
|
||||
{totalFilesDropped ? Strings.pluralize("file", totalFilesDropped) : "files"} to save
|
||||
to Slate
|
||||
</System.H3>
|
||||
<Show when={!totalFilesDropped || totalFilesDropped > 200}>
|
||||
<System.H5 as="p" color="textGrayDark">
|
||||
(we recommend uploading 200 files at a time)
|
||||
</System.H5>
|
||||
</Show>
|
||||
</div>
|
||||
</motion.div>
|
||||
) : null}
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
|
||||
const DroppedFilesPlaceholder = ({ totalFilesDropped = 3 }) => {
|
||||
const marginRight = clamp(totalFilesDropped - 1, 0, 2) * 8;
|
||||
return (
|
||||
<div style={{ position: "relative", right: marginRight }}>
|
||||
<div css={STYLES_PLACEHOLDER}>
|
||||
<FilePlaceholder />
|
||||
</div>
|
||||
<Show when={totalFilesDropped >= 2}>
|
||||
<div
|
||||
style={{ position: "absolute", top: -15, right: -16, zIndex: -1 }}
|
||||
css={STYLES_PLACEHOLDER}
|
||||
>
|
||||
<FilePlaceholder />
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={totalFilesDropped >= 3}>
|
||||
<div
|
||||
style={{ position: "absolute", top: 2 * -15, right: 2 * -16, zIndex: -2 }}
|
||||
css={STYLES_PLACEHOLDER}
|
||||
>
|
||||
<FilePlaceholder />
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -2,17 +2,16 @@ import * as React from "react";
|
||||
import * as Styles from "~/common/styles";
|
||||
import * as System from "~/components/system";
|
||||
import * as Constants from "~/common/constants";
|
||||
import * as SVG from "~/common/svg";
|
||||
import * as Events from "~/common/custom-events";
|
||||
|
||||
import { useUploadContext } from "~/components/core/Upload/Provider";
|
||||
import { Show } from "~/components/utility/Show";
|
||||
import { ModalPortal } from "../ModalPortal";
|
||||
import { motion } from "framer-motion";
|
||||
import { css } from "@emotion/react";
|
||||
import { Provider } from "~/components/core/Upload/Provider";
|
||||
|
||||
import UploadModal from "~/components/core/Upload/Modal";
|
||||
import Popup from "~/components/core/Upload/Popup";
|
||||
import DataMeter from "~/components/core/DataMeter";
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------
|
||||
@ -87,4 +86,4 @@ const UploadMetrics = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export { Provider, Root, Trigger };
|
||||
export { Provider, Root, Popup, Trigger };
|
||||
|
Loading…
Reference in New Issue
Block a user