file-view-text.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { useState, useEffect } from 'react'
  2. import PropTypes from 'prop-types'
  3. import { useProjectContext } from '../../../shared/context/project-context'
  4. const MAX_FILE_SIZE = 2 * 1024 * 1024
  5. export default function FileViewText({ file, onLoad, onError }) {
  6. const { _id: projectId } = useProjectContext({
  7. _id: PropTypes.string.isRequired,
  8. })
  9. const [textPreview, setTextPreview] = useState('')
  10. const [shouldShowDots, setShouldShowDots] = useState(false)
  11. const [inFlight, setInFlight] = useState(false)
  12. useEffect(() => {
  13. if (inFlight) {
  14. return
  15. }
  16. let path = `/project/${projectId}/file/${file.id}`
  17. fetch(path, { method: 'HEAD' })
  18. .then(response => {
  19. if (!response.ok) throw new Error('HTTP Error Code: ' + response.status)
  20. return response.headers.get('Content-Length')
  21. })
  22. .then(fileSize => {
  23. let truncated = false
  24. let maxSize = null
  25. if (fileSize > MAX_FILE_SIZE) {
  26. truncated = true
  27. maxSize = MAX_FILE_SIZE
  28. }
  29. if (maxSize != null) {
  30. path += `?range=0-${maxSize}`
  31. }
  32. return fetch(path).then(response => {
  33. return response.text().then(text => {
  34. if (truncated) {
  35. text = text.replace(/\n.*$/, '')
  36. }
  37. setTextPreview(text)
  38. onLoad()
  39. setShouldShowDots(truncated)
  40. })
  41. })
  42. })
  43. .catch(err => {
  44. console.error(err)
  45. onError()
  46. })
  47. .finally(() => {
  48. setInFlight(false)
  49. })
  50. }, [projectId, file.id, onError, onLoad, inFlight])
  51. return (
  52. <div>
  53. {textPreview && (
  54. <div className="text-preview">
  55. <div className="scroll-container">
  56. <p>{textPreview}</p>
  57. {shouldShowDots && <p>...</p>}
  58. </div>
  59. </div>
  60. )}
  61. </div>
  62. )
  63. }
  64. FileViewText.propTypes = {
  65. file: PropTypes.shape({ id: PropTypes.string }).isRequired,
  66. onLoad: PropTypes.func.isRequired,
  67. onError: PropTypes.func.isRequired,
  68. }