mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-24 02:27:37 +00:00
Add drop target
This commit is contained in:
parent
987d9b20c0
commit
aaffcb13bd
8 changed files with 104 additions and 6 deletions
32
src/App.js
32
src/App.js
|
|
@ -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
11
src/DropTarget.js
Normal 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;
|
||||
|
|
@ -25,7 +25,7 @@ function SearchLogo() {
|
|||
|
||||
class Header extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
super();
|
||||
this._disposable = new Disposable();
|
||||
this._inputRef = null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
53
src/hooks.js
53
src/hooks.js
|
|
@ -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,
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue