From ca11b5e090944e46055bde5d413baa2166901a9f Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sat, 12 Sep 2020 16:35:26 -0700 Subject: [PATCH] Use more hooks --- src/FocusedSkin.js | 235 +++++++++++++++++++++++---------------------- 1 file changed, 118 insertions(+), 117 deletions(-) diff --git a/src/FocusedSkin.js b/src/FocusedSkin.js index 526a5b34..f5f5feb2 100644 --- a/src/FocusedSkin.js +++ b/src/FocusedSkin.js @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useRef } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; import { useSelector } from "react-redux"; import { useActionCreator, useWindowSize } from "./hooks"; import * as Selectors from "./redux/selectors"; @@ -58,31 +58,15 @@ function useCenteredState() { ); } -class BaseFocusedSkin extends React.Component { +class AnimationWrapper extends React.Component { constructor(props) { super(props); this._disposable = new Disposable(); // TODO: Handle the case were we come from a permalink - if (this.props.initialPosition == null) { - this.state = Object.assign( - { - previewLoaded: false, - loaded: false, - transitionComplete: true, - }, - this.props.centeredState - ); - } else { - this.state = { - loaded: false, - centered: false, - transitionComplete: false, - top: this.props.initialPosition.top, - left: this.props.initialPosition.left, - width: this.props.initialWidth, - height: this.props.initialHeight, - }; - } + this.state = { + loaded: false, + centered: this.props.initialPosition == null, + }; this._webampLoadedEvents = new Subject(); this._transitionBeginEvents = new Subject(); const transitionComplete = this._transitionBeginEvents.pipe(delay(500)); @@ -96,6 +80,9 @@ class BaseFocusedSkin extends React.Component { // This value matches the opacity transition timing for `#webamp` in CSS const webampFadeinComplete = startWebampFadein.pipe(delay(400)); + // Once webamp has loaded and the transition is complete, we can start the Webamp fadein + // Once the webamp fadein is complete (400ms) we are "loaded" + this._disposable.add( startWebampFadein.subscribe(() => { document.body.classList.add("webamp-loaded"); @@ -110,11 +97,11 @@ class BaseFocusedSkin extends React.Component { } componentDidMount() { - if (!this.state.centered) { + if (this.props.initialPosition != null) { this._disposable.add( timer(0).subscribe(() => { // TODO: Observe DOM and recenter - this.setState(this.props.centeredState); + this.setState({ centered: true }); this._transitionBeginEvents.next(null); }) ); @@ -132,92 +119,108 @@ class BaseFocusedSkin extends React.Component { }; render() { - const { loaded } = this.state; - const transform = `translateX(${Math.round( - this.state.left - )}px) translateY(${Math.round(this.state.top)}px)`; - - return ( - - {this.state.centered && ( - <> -
- -
- - )} -
-
- {loaded || ( - this.setState({ previewLoaded: true })} - src={Utils.screenshotUrlFromHash(this.props.hash)} - alt={this.props.skinData && this.props.skinData.fileName} - /> - )} -
-
- {this.props.fileExplorerOpen && } - -
- ); + return this.props.children({ + handleWebampLoaded: () => this.handleWebampLoaded(), + centered: this.state.centered, + loaded: this.state.loaded, + }); } } +function BaseFocusedSkin({ + initialPosition, + centered, + hash, + handleWebampLoaded, + loaded, +}) { + const [previewLoaded, setPreviewLoaded] = useState(initialPosition != null); + const centeredState = useCenteredState(); + const closeModal = useActionCreator(Actions.closeModal); + const skinData = useSelector((state) => state.skins[hash] || null); + const fileExplorerOpen = useSelector(Selectors.getFileExplorerOpen); + const openFileExplorer = useActionCreator(Actions.openFileExplorer); + + const absolutePermalink = useSelector( + Selectors.getAbsolutePermalinkUrlFromHashGetter + )(hash); + const pos = + initialPosition == null || centered ? centeredState : initialPosition; + + const transform = `translateX(${Math.round( + pos.left + )}px) translateY(${Math.round(pos.top)}px)`; + + return ( + + {centered && ( + <> +
+ +
+ + )} +
+
+ {loaded || ( + setPreviewLoaded(true)} + src={Utils.screenshotUrlFromHash(hash)} + alt={skinData && skinData.fileName} + /> + )} +
+
+ {fileExplorerOpen && } + +
+ ); +} + function Wrapper({ ...ownProps }) { const hash = useSelector(Selectors.getSelectedSkinHash); const initialPosition = useSelector(Selectors.getSelectedSkinPosition); - const fileExplorerOpen = useSelector(Selectors.getFileExplorerOpen); - const skinData = useSelector((state) => state.skins[hash] || null); - const absolutePermalink = useSelector( - Selectors.getAbsolutePermalinkUrlFromHashGetter - )(hash); - const openFileExplorer = useActionCreator(Actions.openFileExplorer); const selectRelativeSkin = useActionCreator(Actions.selectRelativeSkin); - const closeModal = useActionCreator(Actions.closeModal); useEffect(() => { const subscription = fromEvent(window.document, "keydown").subscribe( @@ -234,8 +237,6 @@ function Wrapper({ ...ownProps }) { useSkinData(); - const centeredState = useCenteredState(); - const prevSkinHash = useRef(null); useEffect(() => { if (hash !== prevSkinHash.current) { @@ -244,19 +245,19 @@ function Wrapper({ ...ownProps }) { } }, [hash]); - const props = { - ...ownProps, - centeredState, - hash, - initialPosition, - fileExplorerOpen, - skinData, - absolutePermalink, - openFileExplorer, - selectRelativeSkin, - closeModal, - }; - return ; + const props = { ...ownProps, hash, initialPosition }; + return ( + + {({ centered, handleWebampLoaded, loaded }) => ( + + )} + + ); } export default Wrapper;