codeViewer: refactor to use hooks
This commit is contained in:
parent
e3e3445b93
commit
17d6add3dc
|
@ -1,43 +1,34 @@
|
||||||
import React from "react"
|
import React, { useState } from "react"
|
||||||
import hljs from "highlight.js"
|
import hljs from "highlight.js"
|
||||||
|
import * as hooks from "./hooks"
|
||||||
import LinkButton from "./util/linkButton"
|
import LinkButton from "./util/linkButton"
|
||||||
|
|
||||||
MAX_HIGHLIGHT_LENGTH = 10 * 1024 # 10 KiB
|
MAX_HIGHLIGHT_LENGTH = 10 * 1024 # 10 KiB
|
||||||
|
|
||||||
class CodeViewer extends React.Component
|
export default CodeViewer = (props) ->
|
||||||
constructor: (props) ->
|
[code, setCode] = useState "Loading..."
|
||||||
super props
|
[highlight, setHighlight] = useState true
|
||||||
@state =
|
|
||||||
code: "Loading..."
|
|
||||||
highlight: true
|
|
||||||
|
|
||||||
componentDidMount: ->
|
# Fetch the content on first mount (and after first render)
|
||||||
resp = await fetch "/paste/#{@props.id}?original"
|
hooks.useFetchContent props.id, (meta, resp) ->
|
||||||
resp = await resp.text()
|
resp = await resp.text()
|
||||||
if resp.length < MAX_HIGHLIGHT_LENGTH
|
if meta.length < MAX_HIGHLIGHT_LENGTH
|
||||||
resp = hljs.highlightAuto(resp).value
|
setCode hljs.highlightAuto(resp).value
|
||||||
else
|
else
|
||||||
@setState
|
setHighlight false
|
||||||
highlight: false
|
setCode resp
|
||||||
|
|
||||||
@setState
|
|
||||||
code: resp
|
|
||||||
|
|
||||||
render: ->
|
|
||||||
if @state.switchToHome
|
|
||||||
return <Redirect push to="/paste/text" />
|
|
||||||
|
|
||||||
<div className="content-pastebin">
|
<div className="content-pastebin">
|
||||||
<div
|
<div
|
||||||
className="content-code-viewer"
|
className="content-code-viewer"
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
if @state.highlight
|
if highlight
|
||||||
<pre
|
<pre
|
||||||
dangerouslySetInnerHTML={{__html: @state.code}}
|
dangerouslySetInnerHTML={{__html: code}}
|
||||||
/>
|
/>
|
||||||
else
|
else
|
||||||
<pre>{@state.code}</pre>
|
<pre>{code}</pre>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="content-buttons">
|
<div className="content-buttons">
|
||||||
|
@ -50,5 +41,3 @@ class CodeViewer extends React.Component
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
export default CodeViewer
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState, useCallback } from "react"
|
import React, { useState, useCallback, useEffect } from "react"
|
||||||
import ReactModal from "react-modal"
|
import ReactModal from "react-modal"
|
||||||
|
|
||||||
# Simple abstraction for a toggling state
|
# Simple abstraction for a toggling state
|
||||||
|
@ -91,3 +91,31 @@ export usePaste = (openDialog, callback) ->
|
||||||
pasting,
|
pasting,
|
||||||
progress
|
progress
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# An effect that fetches the original pasted content,
|
||||||
|
# and then fires a callback that handles metadata and the response body
|
||||||
|
# it also stores the meta into a state and returns it every time
|
||||||
|
# this hook gets called, so callbacks are not necessary
|
||||||
|
# and if callback is not present, then the response body
|
||||||
|
# would simply be thrown away
|
||||||
|
export useFetchContent = (id, callback) ->
|
||||||
|
[meta, setMeta] = useState null
|
||||||
|
|
||||||
|
doFetch = ->
|
||||||
|
resp = await fetch "/paste/#{id}?original"
|
||||||
|
length = resp.headers.get 'content-length'
|
||||||
|
mime = resp.headers.get 'content-type'
|
||||||
|
[_, name] = resp.headers.get 'content-disposition'
|
||||||
|
.split 'filename*='
|
||||||
|
newMeta =
|
||||||
|
name: name
|
||||||
|
mime: mime
|
||||||
|
length: length
|
||||||
|
setMeta newMeta
|
||||||
|
# We have to pass newMeta to callback because
|
||||||
|
# the callback will not be aware of the meta update
|
||||||
|
callback newMeta, resp if callback
|
||||||
|
|
||||||
|
# Run the effect once on mount
|
||||||
|
useEffect doFetch, []
|
||||||
|
meta
|
Loading…
Reference in a new issue