Add drop target

This commit is contained in:
Jordan Eldredge 2020-09-12 23:17:43 -07:00
parent 987d9b20c0
commit aaffcb13bd
8 changed files with 104 additions and 6 deletions

View file

@ -1,4 +1,4 @@
import React from "react";
import React, { useCallback } from "react";
import { connect } from "react-redux";
import Head from "./Head";
import About from "./About";
@ -8,10 +8,17 @@ import SkinTable from "./SkinTable";
import FocusedSkin from "./FocusedSkin";
import { useSelector } from "react-redux";
import * as Selectors from "./redux/selectors";
import * as Actions from "./redux/actionCreators";
import { ABOUT_PAGE } from "./constants";
import { useWindowSize, useScrollbarWidth } from "./hooks";
import {
useWindowSize,
useScrollbarWidth,
useDropFiles,
useActionCreator,
} from "./hooks";
import { SCREENSHOT_WIDTH, SKIN_RATIO } from "./constants";
import UploadGrid from "./UploadGrid";
import DropTarget from "./DropTarget";
import Metadata from "./components/Metadata";
import SkinReadme from "./SkinReadme";
@ -22,6 +29,21 @@ const getTableDimensions = (windowWidth, scale) => {
return { columnWidth, rowHeight, columnCount };
};
function useDropTarget() {
const gotFiles = useActionCreator(Actions.gotFiles);
const areDragging = useSelector(Selectors.getAreDragging);
const onDrop = useCallback(
(e) => {
gotFiles(Array.from(e.dataTransfer.files));
},
[gotFiles]
);
const setDragging = useActionCreator(Actions.setDragging);
useDropFiles({ onDrop, setDragging });
return areDragging;
}
function App(props) {
const scrollbarWidth = useScrollbarWidth();
const {
@ -36,11 +58,15 @@ function App(props) {
const fileExplorerOpen = useSelector(Selectors.getFileExplorerOpen);
const areDragging = useDropTarget();
return (
<div>
<Head />
<Header />
{props.uploadViewOpen ? (
{areDragging ? (
<DropTarget />
) : props.uploadViewOpen ? (
<UploadGrid />
) : (
<SkinTable

11
src/DropTarget.js Normal file
View file

@ -0,0 +1,11 @@
import React from "react";
import { HEADING_HEIGHT } from "./constants";
function DropTarget() {
return (
<div style={{ color: "white", marginTop: HEADING_HEIGHT }}>
<h1>Drop</h1>
</div>
);
}
export default DropTarget;

View file

@ -25,7 +25,7 @@ function SearchLogo() {
class Header extends React.Component {
constructor(props) {
super(props);
super();
this._disposable = new Disposable();
this._inputRef = null;
}

View file

@ -1,4 +1,4 @@
import * as React from "react";
import React from "react";
import { useSelector } from "react-redux";
import { useActionCreator } from "./hooks";
import * as Actions from "./redux/actionCreators";
@ -12,6 +12,7 @@ function UploadButton() {
const uploadViewOpen = useSelector(Selectors.getHaveUploadFiles);
const gotFiles = useActionCreator(Actions.gotFiles);
const closeUploadFiles = useActionCreator(Actions.closeUploadFiles);
if (!SHOW_UPLOAD) {
return null;
}

View file

@ -1,5 +1,5 @@
import * as Utils from "./utils";
import { useMemo, useState, useEffect, useCallback } from "react";
import { useMemo, useState, useEffect, useCallback, useRef } from "react";
import { useDispatch } from "react-redux";
import { delay } from "rxjs/operators";
@ -100,3 +100,54 @@ export function useWebampAnimation({ initialPosition }) {
handleWebampLoaded: () => webampLoadedEvents.next(null),
};
}
export function useDropFiles({ onDrop, setDragging }) {
const onDragEnterCallback = useCallback(
(e) => {
e.preventDefault();
setDragging(true);
},
[setDragging]
);
const onDragLeaveCallback = useCallback(
(e) => {
e.preventDefault();
if (e.target === window.document.documentElement) {
setDragging(false);
}
},
[setDragging]
);
const onDropCallback = useCallback(
(e) => {
e.preventDefault();
setDragging(false);
onDrop(e);
},
[onDrop, setDragging]
);
const onDragoverCallback = useCallback((e) => {
e.preventDefault();
}, []);
useEffect(() => {
window.addEventListener("drop", onDropCallback);
window.addEventListener("dragover", onDragoverCallback);
window.addEventListener("dragenter", onDragEnterCallback);
window.addEventListener("dragleave", onDragLeaveCallback);
return () => {
window.removeEventListener("drop", onDropCallback);
window.removeEventListener("dragover", onDragoverCallback);
window.removeEventListener("dragenter", onDragEnterCallback);
window.removeEventListener("dragleave", onDragLeaveCallback);
};
}, [
onDropCallback,
onDragoverCallback,
onDragEnterCallback,
onDragLeaveCallback,
]);
}

View file

@ -38,6 +38,10 @@ export function doesNotConcentToNsfw() {
return { type: "DOES_NOT_CONCENT_TO_NSFW" };
}
export function setDragging(dragging) {
return { type: "SET_DRAGGING", dragging };
}
export function toggleUploadView() {
return { type: "TOGGLE_UPLOAD_VIEW" };
}

View file

@ -10,6 +10,7 @@ const defaultState = {
focusedSkinFile: null,
fileExplorerOpen: false,
uploadViewOpen: false,
areDragging: false,
activeContentPage: null,
totalNumberOfSkins: null,
scale: 0.5,
@ -20,6 +21,8 @@ const defaultState = {
export default function reducer(state = defaultState, action) {
switch (action.type) {
case "SET_DRAGGING":
return { ...state, areDragging: action.dragging };
case "SET_SCALE": {
return { ...state, scale: action.scale };
}

View file

@ -50,6 +50,8 @@ export const getFileToUpload = (state) => {
export const getHaveUploadFiles = (state) =>
Object.keys(state.fileUploads).length > 0;
export const getAreDragging = (state) => state.areDragging;
/**
* Skin Interface
* {