From 2539f671451a15f0566dbcd609e2bda5dfd9a162 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sun, 13 Sep 2020 14:14:37 -0700 Subject: [PATCH] Make the upload page its own route --- src/App.js | 31 +++--- src/DropTarget.js | 38 -------- src/Header.js | 184 ++++++++++++++++-------------------- src/UploadButton.js | 27 +++--- src/UploadGrid.js | 69 ++++++++++---- src/constants.js | 1 + src/redux/actionCreators.js | 7 +- src/redux/epics.js | 3 + src/redux/reducer.js | 11 ++- src/redux/selectors.js | 10 +- 10 files changed, 184 insertions(+), 197 deletions(-) delete mode 100644 src/DropTarget.js diff --git a/src/App.js b/src/App.js index 685dc9b0..6e99266c 100644 --- a/src/App.js +++ b/src/App.js @@ -10,15 +10,9 @@ 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, - useDropFiles, - useActionCreator, -} from "./hooks"; -import { SCREENSHOT_WIDTH, SKIN_RATIO, SHOW_UPLOAD } from "./constants"; +import { useWindowSize, useScrollbarWidth, 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"; import { useDropzone } from "react-dropzone"; @@ -50,11 +44,10 @@ function App(props) { }, [gotFiles] ); - const { - getRootProps, - getInputProps, - isDragActive: areDragging, - } = useDropzone({ onDrop }); + const { getRootProps, getInputProps, isDragActive } = useDropzone({ + onDrop, + noClick: true, + }); const fileExplorerOpen = useSelector(Selectors.getFileExplorerOpen); @@ -62,10 +55,8 @@ function App(props) {
- {areDragging && SHOW_UPLOAD ? ( - - ) : props.uploadViewOpen ? ( - + {props.uploadViewOpen || isDragActive ? ( + ) : ( )} - {props.aboutPage ? ( + {props.page === ABOUT_PAGE ? ( @@ -100,9 +91,9 @@ function App(props) { const mapStateToProps = (state) => ({ selectedSkinHash: Selectors.getSelectedSkinHash(state), overlayShouldAnimate: Selectors.overlayShouldAnimate(state), - aboutPage: Selectors.getActiveContentPage(state) === ABOUT_PAGE, + page: Selectors.getActiveContentPage(state), scale: state.scale, - uploadViewOpen: Selectors.getHaveUploadFiles(state), + uploadViewOpen: Selectors.getUploadViewOpen(state), }); export default connect(mapStateToProps)(App); diff --git a/src/DropTarget.js b/src/DropTarget.js deleted file mode 100644 index 34c783ec..00000000 --- a/src/DropTarget.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from "react"; -import { HEADING_HEIGHT } from "./constants"; - -function DropTarget({ getInputProps }) { - return ( -
-
- Drop Skins Here - -
-
- ); -} -export default DropTarget; diff --git a/src/Header.js b/src/Header.js index 3e35b7fa..8fa8f507 100644 --- a/src/Header.js +++ b/src/Header.js @@ -1,10 +1,9 @@ -import * as React from "react"; -import { connect } from "react-redux"; +import React, { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; import * as Utils from "./utils"; import * as Selectors from "./redux/selectors"; import * as Actions from "./redux/actionCreators"; -import Disposable from "./Disposable"; -import { useWindowSize } from "./hooks"; +import { useActionCreator, useWindowSize } from "./hooks"; import { ReactComponent as AlgoliaLogo } from "./searchByAlgoliaDarkbBackground.svg"; import algoliaLogoSmallUrl from "./searchByAlgoliaSmall.png"; import UploadButton from "./UploadButton"; @@ -23,67 +22,73 @@ function SearchLogo() { ); } -class Header extends React.Component { - constructor(props) { - super(); - this._disposable = new Disposable(); - this._inputRef = null; - } +function useFocusOnSlash() { + const [input, setInput] = useState(null); - componentDidMount() { + useEffect(() => { + if (input == null) { + return; + } const handler = (e) => { // slash if (e.keyCode === 191) { - if (this._inputRef == null) { - return; - } - if (this._inputRef !== document.activeElement) { - this._inputRef.focus(); + if (input !== document.activeElement) { + input.focus(); e.preventDefault(); } } }; window.document.addEventListener("keydown", handler); - this._disposable.add(() => { + return () => { window.document.removeEventListener("keydown", handler); - }); - } + }; + }, [input]); - componentWillUnmount() { - this._disposable.dispose(); - } - render() { - return ( - - ); - } + setSearchQuery(e.target.value)} + value={searchQuery || ""} + placeholder={"Search..."} + ref={setInput} + /> + + + + )} + +
+ ); } -const mapStateToProps = (state) => ({ - searchQuery: Selectors.getSearchQuery(state), - scale: state.scale, - uploadViewOpen: Selectors.getHaveUploadFiles(state), -}); - -const mapDispatchToProps = (dispatch) => ({ - setSearchQuery(query) { - dispatch(Actions.searchQueryChanged(query)); - }, - requestRandomSkin() { - dispatch(Actions.requestedRandomSkin()); - }, - requestedAboutPage() { - dispatch(Actions.requestedAboutPage()); - }, - setScale(scale) { - dispatch({ type: "SET_SCALE", scale }); - }, -}); -export default connect(mapStateToProps, mapDispatchToProps)(Header); +export default Header; diff --git a/src/UploadButton.js b/src/UploadButton.js index 32a47135..0212a5c2 100644 --- a/src/UploadButton.js +++ b/src/UploadButton.js @@ -5,27 +5,28 @@ import * as Actions from "./redux/actionCreators"; import { SHOW_UPLOAD } from "./constants"; import UploadIcon from "./components/icons/UploadIcon"; import CloseIcon from "./components/icons/CloseIcon"; -import { promptForFileReferences } from "./utils"; import * as Selectors from "./redux/selectors"; function UploadButton() { - const uploadViewOpen = useSelector(Selectors.getHaveUploadFiles); - const gotFiles = useActionCreator(Actions.gotFiles); + const uploadViewOpen = useSelector(Selectors.getUploadViewOpen); const closeUploadFiles = useActionCreator(Actions.closeUploadFiles); + const requestedUploadPage = useActionCreator(Actions.requestedUploadPage); if (!SHOW_UPLOAD) { - return null; + // return null; } - const style = { paddingLeft: "0.2rem", paddingRight: "0.2rem" }; + const style = { + paddingLeft: "0.2rem", + paddingRight: "0.2rem", + }; + + // TODO: Make these buttons links. if (uploadViewOpen) { return ( } - - - - - - - - - - {Object.values(files).map((file, i) => { - return ; - })} - -
ActionFilenameStatus
+
+ {isDragActive || Object.keys(files).length === 0 ? ( +
+ Drop Skins Here + +
+ ) : ( + <> + {canUpload && ( + + )} + + + + + + + + + + {Object.values(files).map((file, i) => { + return ; + })} + +
ActionFilenameStatus
+ + )}
); } diff --git a/src/constants.js b/src/constants.js index 0ee6c46d..28ecf4cf 100644 --- a/src/constants.js +++ b/src/constants.js @@ -2,6 +2,7 @@ export const SCREENSHOT_WIDTH = 275; export const SCREENSHOT_HEIGHT = 348; export const SKIN_RATIO = SCREENSHOT_HEIGHT / SCREENSHOT_WIDTH; export const ABOUT_PAGE = "ABOUT_PAGE"; +export const UPLOAD_PAGE = "UPLOAD_PAGE"; // export const CDN = "https://s3.amazonaws.com/webamp-uploaded-skins"; // export const CDN = "https://s3.amazonaws.com/cdn.webampskins.org"; export const SCREENSHOT_CDN = "https://cdn.webampskins.org"; diff --git a/src/redux/actionCreators.js b/src/redux/actionCreators.js index 3fd6c3ba..0ea38f2d 100644 --- a/src/redux/actionCreators.js +++ b/src/redux/actionCreators.js @@ -1,3 +1,4 @@ +import { ABOUT_PAGE, UPLOAD_PAGE } from "../constants"; export function closeModal() { return { type: "CLOSE_MODAL" }; } @@ -109,7 +110,11 @@ export function gotFocusedSkinFile(content) { } export function requestedAboutPage() { - return { type: "REQUESTED_ABOUT_PAGE" }; + return { type: "REQUESTED_PAGE", page: ABOUT_PAGE }; +} + +export function requestedUploadPage() { + return { type: "REQUESTED_PAGE", page: UPLOAD_PAGE }; } export function selectRelativeSkin(offset) { diff --git a/src/redux/epics.js b/src/redux/epics.js index eddc0e35..7f92bfb7 100644 --- a/src/redux/epics.js +++ b/src/redux/epics.js @@ -27,6 +27,9 @@ const urlChangedEpic = (actions) => if (action.location.pathname === "/about/") { return of(Actions.requestedAboutPage()); } + if (action.location.pathname === "/upload/") { + return of(Actions.requestedUploadPage()); + } const params = new URLSearchParams(action.location.search); const query = params != null && params.get("query"); diff --git a/src/redux/reducer.js b/src/redux/reducer.js index 3be4ae0b..1ee5f2d2 100644 --- a/src/redux/reducer.js +++ b/src/redux/reducer.js @@ -1,4 +1,4 @@ -import { ABOUT_PAGE, CHUNK_SIZE } from "../constants"; +import { CHUNK_SIZE, UPLOAD_PAGE } from "../constants"; const defaultState = { searchQuery: null, @@ -26,6 +26,9 @@ export default function reducer(state = defaultState, action) { case "SET_SCALE": { return { ...state, scale: action.scale }; } + case "GOT_FILES": { + return { ...state, activeContentPage: UPLOAD_PAGE }; + } case "GOT_FILE": { return { ...state, @@ -141,6 +144,7 @@ export default function reducer(state = defaultState, action) { case "CLOSE_UPLOAD_FILES": { return { ...state, + activeContentPage: null, fileUploads: {}, }; } @@ -248,10 +252,11 @@ export default function reducer(state = defaultState, action) { content: action.content, }, }; - case "REQUESTED_ABOUT_PAGE": + case "REQUESTED_PAGE": + console.log(action); return { ...state, - activeContentPage: ABOUT_PAGE, + activeContentPage: action.page, }; case "OPEN_FILE_EXPLORER": return { diff --git a/src/redux/selectors.js b/src/redux/selectors.js index 941aa06a..dee75eb5 100644 --- a/src/redux/selectors.js +++ b/src/redux/selectors.js @@ -1,6 +1,6 @@ import { createSelector } from "reselect"; import * as Utils from "../utils"; -import { ABOUT_PAGE } from "../constants"; +import { ABOUT_PAGE, UPLOAD_PAGE } from "../constants"; export function getSelectedSkinHash(state) { return state.selectedSkinHash; @@ -47,8 +47,9 @@ export const getFileToUpload = (state) => { ); }; -export const getHaveUploadFiles = (state) => - Object.keys(state.fileUploads).length > 0; +export const getUploadViewOpen = (state) => { + return state.activeContentPage === UPLOAD_PAGE; +}; export const getAreDragging = (state) => state.areDragging; @@ -145,6 +146,9 @@ export const getUrl = createSelector( if (activeContentPage === ABOUT_PAGE) { return "/about/"; } + if (activeContentPage === UPLOAD_PAGE) { + return "/upload/"; + } if (hash) { const skinUrl = getPermalinkUrlFromHash(hash); if (fileExplorerOpen && focusedSkinFile) {