helpButton, openDialog: refactor using hooks and context

This commit is contained in:
Peter Cai 2020-02-20 13:02:40 +08:00
parent 0f6b4e06f1
commit 6c15b51296
No known key found for this signature in database
GPG Key ID: 71F5FB4E4F3FD54F
6 changed files with 56 additions and 55 deletions

View File

@ -7,7 +7,6 @@ import * as crypto from "../crypto"
import * as util from "../util"
export default BinaryUpload = ->
[openDialog, renderDialog] = hooks.useDialog()
[encrypt, toggleEncrypt] = hooks.useToggle false
[encrypting, setEncrypting] = useState false
[file, setFile] = useState null
@ -15,8 +14,7 @@ export default BinaryUpload = ->
# Paste hook and event
clearFile = (status) ->
setFile null if status == 200
[doPaste, pasting, progress] = hooks.usePaste openDialog,
useCallback clearFile, []
[doPaste, pasting, progress] = hooks.usePaste useCallback clearFile, []
# Dropzone hook and event
onDrop = (files) ->
@ -38,7 +36,6 @@ export default BinaryUpload = ->
doUpload = useCallback doUpload, [file, encrypt, doPaste]
<div className="content-pastebin">
{renderDialog()}
<section className="container">
<div {...getRootProps({className: 'dropzone'})}>
<input {...getInputProps()} />
@ -54,7 +51,7 @@ export default BinaryUpload = ->
</aside>
</section>
<div className="content-buttons">
<HelpButton openDialog={openDialog} />
<HelpButton />
<button
className="button-blue"
disabled={pasting}

View File

@ -0,0 +1,4 @@
import React from "react"
# The value should be a function `openDialog(msg)`
export default DialogContext = React.createContext null

View File

@ -1,12 +1,12 @@
import React from "react"
import React, { useContext, useCallback } from "react"
import DialogContext from "./dialogContext"
import * as util from "../util"
class HelpButton extends React.Component
constructor: (props) ->
super props
export default HelpButton = ->
openDialog = useContext DialogContext
showHelp: =>
@props.openDialog do =>
showHelp = ->
openDialog do ->
<React.Fragment>
<p><strong>Angry.Im Pastebin Service</strong><br/>
Source code:&nbsp;
@ -31,13 +31,11 @@ class HelpButton extends React.Component
The decryption will also be done entirely in your browser. Therefore, it is not supported to access encrypted files outside of a modern browser.
</p>
</React.Fragment>
showHelp = useCallback showHelp, [openDialog]
render: ->
<button
className="button-blue"
onClick={@showHelp}
>
Help
</button>
export default HelpButton
<button
className="button-blue"
onClick={showHelp}
>
Help
</button>

View File

@ -2,6 +2,7 @@ import React, { useState } from "react"
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom"
import { AnimatedSwitch, spring } from 'react-router-transition'
import * as hooks from "./hooks"
import DialogContext from "./dialogContext"
import Pastebin from "./pastebin"
import BinaryUpload from "./binaryUpload"
import FileViewerDispatcher from "./fileViewerDispatcher"
@ -32,33 +33,35 @@ export default Home = ->
<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>
<DialogContext.Provider value={openDialog}>
<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 />}
/>
<Route
exact path="/paste/binary"
render={() => <BinaryUpload />}
/>
<Route
path="/paste/:id"
component={FileViewerDispatcher}
/>
</AnimatedSwitch>
</Router>
</DialogContext.Provider>
</div>
{renderDialog()}
</div>

View File

@ -1,5 +1,6 @@
import React, { useState, useCallback, useEffect } from "react"
import React, { useState, useCallback, useEffect, useContext } from "react"
import ReactModal from "react-modal"
import DialogContext from "./dialogContext"
# Simple abstraction for a toggling state
export useToggle = (defVal) ->
@ -73,7 +74,8 @@ export useXhrProgress = ->
]
# Handles shared file-uploading logic between text / binary pasting
export usePaste = (openDialog, callback) ->
export usePaste = (callback) ->
openDialog = useContext DialogContext
[pasting, setPasting] = useState false
[progress, _, beginXHR] = useXhrProgress()

View File

@ -1,19 +1,17 @@
import React, { useState, useCallback } from "react"
import React, { useState, useCallback, useContext } from "react"
import * as hooks from "./hooks"
import HelpButton from "./helpButton"
import LinkButton from "./util/linkButton"
import ContentEditable from "./util/contentEditable"
export default Pastebin = ->
[openDialog, renderDialog] = hooks.useDialog()
[highlight, toggleHighlight] = hooks.useToggle false
[text, setText] = useState ""
# Paste hook and events
clearText = (status) ->
setText "" if status == 200
[doPaste, pasting, _] = hooks.usePaste openDialog,
useCallback clearText, []
[doPaste, pasting, _] = hooks.usePaste useCallback clearText, []
onEditTextUpdate = (ev) ->
setText ev.target.value
@ -28,7 +26,6 @@ export default Pastebin = ->
paste = useCallback paste, [text, doPaste]
<div className="content-pastebin">
{renderDialog()}
<ContentEditable
className="content-pastebin-edit"
onUpdate={onEditTextUpdate}
@ -37,7 +34,7 @@ export default Pastebin = ->
plainText
/>
<div className="content-buttons">
<HelpButton openDialog={openDialog} />
<HelpButton />
<button
className="button-blue"
onClick={toggleHighlight}