fix transition between pages by using a custom LinkButton

by replacing everything with a `<Redirect/>` on switching, it produces a
short blink while the new page appears. But we cannot just use `<Link/>`
because an `<a>` cannot be "disabled". Wrapping `Link` around `button`
is invalid HTML5.

Instead, hack together a custom component for the job.
This commit is contained in:
Peter Cai 2020-02-19 19:17:57 +08:00
parent 3169a7825f
commit 2b42e19ecb
No known key found for this signature in database
GPG Key ID: 71F5FB4E4F3FD54F
5 changed files with 45 additions and 24 deletions

View File

@ -1,6 +1,6 @@
import React from "react"
import { Redirect } from "react-router-dom"
import Dropzone from "react-dropzone"
import LinkButton from "./util/linkButton"
import * as crypto from "../crypto"
import * as util from "../util"
@ -11,7 +11,6 @@ class BinaryUpload extends React.Component
file: null
uploading: false
progress: 0
switchToText: false
encrypt: false
encrypting: false
@ -70,9 +69,6 @@ class BinaryUpload extends React.Component
{ encrypt: not state.encrypt }
render: ->
if @state.switchToText
return <Redirect to="/paste/text" />
<div className="content-pastebin">
<Dropzone onDrop={@onDrop}>
{({getRootProps, getInputProps}) =>
@ -100,13 +96,13 @@ class BinaryUpload extends React.Component
>
{ "Encrypt: " + if @state.encrypt then "ON" else "OFF" }
</button>
<button
<LinkButton
className="button-blue"
disabled={@state.uploading}
onClick={(ev) => @setState { switchToText: true }}
to="/paste/text"
>
Text Mode
</button>
</LinkButton>
<button
className="button-blue"
disabled={@state.uploading or not @state.file}

View File

@ -1,6 +1,6 @@
import React from "react"
import { Redirect } from "react-router-dom"
import hljs from "highlight.js"
import LinkButton from "./util/linkButton"
MAX_HIGHLIGHT_LENGTH = 10 * 1024 # 10 KiB
@ -9,7 +9,6 @@ class CodeViewer extends React.Component
super props
@state =
code: "Loading..."
switchToHome: false
highlight: true
componentDidMount: ->
@ -42,12 +41,13 @@ class CodeViewer extends React.Component
}
</div>
<div className="content-buttons">
<button
<LinkButton
className="button-blue"
onClick={(ev) => @setState { switchToHome: true }}
push
to="/paste/text"
>
New Paste
</button>
</LinkButton>
</div>
</div>

View File

@ -1,5 +1,5 @@
import React from "react"
import { Link } from "react-router-dom"
import LinkButton from "./util/linkButton"
import * as crypto from "../crypto"
import * as util from "../util"
@ -119,12 +119,13 @@ class FileDecrypter extends React.Component
</a>
}
<br/>
<Link
<LinkButton
className="button-blue"
push
to="/paste/text"
>
Home
</Link>
</LinkButton>
</div>
}</div>

View File

@ -1,5 +1,5 @@
import React from "react"
import { Redirect } from "react-router-dom"
import LinkButton from "./util/linkButton"
import ContentEditable from "./util/contentEditable"
class Pastebin extends React.Component
@ -9,7 +9,6 @@ class Pastebin extends React.Component
text: ""
pasting: false
highlight: false # Make this false by default to avoid blocking
switchToUpload: false
onEditTextUpdate: (ev) =>
console.log ev.target.value
@ -54,9 +53,6 @@ class Pastebin extends React.Component
pasting: false
render: ->
if @state.switchToUpload
return <Redirect to="/paste/binary" />
<div className="content-pastebin">
<ContentEditable
className="content-pastebin-edit"
@ -72,13 +68,13 @@ class Pastebin extends React.Component
>
Highlight: {if @state.highlight then 'ON' else 'OFF'}
</button>
<button
<LinkButton
className="button-blue"
disabled={@state.pasting}
onClick={(ev) => @setState { switchToUpload: true }}
to="/paste/binary"
>
File Upload
</button>
</LinkButton>
<button
className="button-blue"
disabled={@state.pasting}

View File

@ -0,0 +1,28 @@
import React from "react"
import { Redirect } from "react-router-dom"
# A replacement of react Link that uses a button
class LinkButton extends React.Component
constructor: (props) ->
super props
@state =
switch: false
render: ->
# We cannot just replace the button with a <Redirect/> when we switch
# because it will cause visual breaks where the button disappears for
# a short while before the actual switch happens.
# Use <ins> as a dumb wrapper because it does not actually create
# an element around our tags.
# (the semantics of <ins> is "inserted content", but this seems
# to be the only sane solution here)
# <https://stackoverflow.com/questions/14162035/how-to-wrap-arbitrary-html-with-a-wrapper-without-breaking-markup>
<ins>
<button {...@props} onClick={(e) => @setState { switch: true }}/>
{
@state.switch and
<Redirect {...@props} />
}
</ins>
export default LinkButton