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