diff --git a/src/web/codeViewer.coffee b/src/web/codeViewer.coffee
index 6f17fc0..767dae1 100644
--- a/src/web/codeViewer.coffee
+++ b/src/web/codeViewer.coffee
@@ -1,54 +1,43 @@
-import React from "react"
+import React, { useState } from "react"
import hljs from "highlight.js"
+import * as hooks from "./hooks"
import LinkButton from "./util/linkButton"
MAX_HIGHLIGHT_LENGTH = 10 * 1024 # 10 KiB
-class CodeViewer extends React.Component
- constructor: (props) ->
- super props
- @state =
- code: "Loading..."
- highlight: true
+export default CodeViewer = (props) ->
+ [code, setCode] = useState "Loading..."
+ [highlight, setHighlight] = useState true
- componentDidMount: ->
- resp = await fetch "/paste/#{@props.id}?original"
+ # Fetch the content on first mount (and after first render)
+ hooks.useFetchContent props.id, (meta, resp) ->
resp = await resp.text()
- if resp.length < MAX_HIGHLIGHT_LENGTH
- resp = hljs.highlightAuto(resp).value
+ if meta.length < MAX_HIGHLIGHT_LENGTH
+ setCode hljs.highlightAuto(resp).value
else
- @setState
- highlight: false
+ setHighlight false
+ setCode resp
- @setState
- code: resp
-
- render: ->
- if @state.switchToHome
- return
-
-
-
- {
- if @state.highlight
-
- else
-
{@state.code}
- }
-
-
-
- New Paste
-
-
+
+
+ {
+ if highlight
+
+ else
+
{code}
+ }
-
-export default CodeViewer
\ No newline at end of file
+
+
+ New Paste
+
+
+
\ No newline at end of file
diff --git a/src/web/hooks.coffee b/src/web/hooks.coffee
index e88cdb2..25b484c 100644
--- a/src/web/hooks.coffee
+++ b/src/web/hooks.coffee
@@ -1,4 +1,4 @@
-import React, { useState, useCallback } from "react"
+import React, { useState, useCallback, useEffect } from "react"
import ReactModal from "react-modal"
# Simple abstraction for a toggling state
@@ -90,4 +90,32 @@ export usePaste = (openDialog, callback) ->
useCallback(doPaste, [openDialog, callback]),
pasting,
progress
- ]
\ No newline at end of file
+ ]
+
+# 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
\ No newline at end of file