home: rewrite using React Hooks

This commit is contained in:
Peter Cai 2020-02-20 08:47:35 +08:00
parent 73de387ec5
commit 597c6c9359
No known key found for this signature in database
GPG key ID: 71F5FB4E4F3FD54F
2 changed files with 83 additions and 67 deletions

View file

@ -1,7 +1,7 @@
import React from "react" import React, { useState } from "react"
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom" import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom"
import { AnimatedSwitch, spring } from 'react-router-transition' import { AnimatedSwitch, spring } from 'react-router-transition'
import ReactModal from "react-modal" import * as hooks from "./hooks"
import Pastebin from "./pastebin" import Pastebin from "./pastebin"
import BinaryUpload from "./binaryUpload" import BinaryUpload from "./binaryUpload"
import FileViewerDispatcher from "./fileViewerDispatcher" import FileViewerDispatcher from "./fileViewerDispatcher"
@ -11,71 +11,54 @@ bounce = (val) ->
stiffness: 330 stiffness: 330
damping: 22 damping: 22
class Home extends React.Component atEnter =
constructor: (props) -> opacity: 0
super props translateY: -5
@state =
dialogOpen: false
dialogMsg: null
openDialog: (msg) => atLeave =
@setState opacity: bounce 0
dialogOpen: true translateY: bounce -5
dialogMsg: msg
render: -> atActive =
<div className="content-wrapper"> opacity: bounce 1
<div className="content"> translateY: bounce 0
<Router>
<AnimatedSwitch mapStyles = (styles) ->
atEnter={{ opacity: 0, translateY: -5 }} opacity: styles.opacity
atLeave={{ opacity: bounce(0), translateY: bounce(-5) }} transform: "translateY(#{styles.translateY}%)"
atActive={{ opacity: bounce(1), translateY: bounce(0) }}
mapStyles={(styles) -> export default Home = ->
opacity: styles.opacity [openDialog, renderDialog] = hooks.useDialog()
transform: "translateY(#{styles.translateY}%)"
} <div className="content-wrapper">
className="switch-wrapper" <div className="content">
> <Router>
<Redirect exact from="/" to="/paste/text" /> <AnimatedSwitch
{ atEnter={atEnter}
# Use `render` instead of `component` to prevent re-rendering the child atLeave={atLeave}
# when parent is re-rendered (however this prevents passing match props) atActive={atActive}
} mapStyles={mapStyles}
<Route className="switch-wrapper"
exact path="/paste/text" >
render={() => <Pastebin openDialog={@openDialog}/>} <Redirect exact from="/" to="/paste/text" />
/> {
<Route # Use `render` instead of `component` to prevent re-rendering the child
exact path="/paste/binary" # when parent is re-rendered (however this prevents passing match props)
render={() => <BinaryUpload openDialog={@openDialog}/>} }
/> <Route
<Route exact path="/paste/text"
path="/paste/:id" render={() => <Pastebin openDialog={openDialog}/>}
component={FileViewerDispatcher} />
/> <Route
</AnimatedSwitch> exact path="/paste/binary"
</Router> render={() => <BinaryUpload openDialog={openDialog}/>}
</div> />
{ <Route
# Provide modal dialog for all child path="/paste/:id"
# passed through the openDialog prop component={FileViewerDispatcher}
} />
<ReactModal </AnimatedSwitch>
isOpen={@state.dialogOpen} </Router>
className="ReactModal__Content_My"
closeTimeoutMS={500}
>
<p>{@state.dialogMsg}</p>
<div className="dialog-buttons">
<button
className="button-blue"
onClick={(e) => @setState { dialogOpen: false }}
>
Close
</button>
</div>
</ReactModal>
</div> </div>
{renderDialog()}
export default Home </div>

33
src/web/hooks.coffee Normal file
View file

@ -0,0 +1,33 @@
import React, { useState } from "react"
import ReactModal from "react-modal"
# A hook to support opening dialogs from the code
# returns [openDialog, renderDialog]
# renderDialog should always be called somewhere
# when rending the page
export useDialog = ->
[dialogOpen, setDialogOpen] = useState false
[dialogMsg, setDialogMsg] = useState null
openDialog = (msg) ->
setDialogMsg msg
setDialogOpen true
renderDialog = ->
<ReactModal
isOpen={dialogOpen}
className="ReactModal__Content_My"
closeTimeoutMS={500}
>
<p>{dialogMsg}</p>
<div className="dialog-buttons">
<button
className="button-blue"
onClick={(e) -> setDialogOpen false}
>
Close
</button>
</div>
</ReactModal>
[openDialog, renderDialog]