file-view-text.jsx 2.1 KB

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