binary-file.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import React, { useState } from 'react'
  2. import PropTypes from 'prop-types'
  3. import { useTranslation } from 'react-i18next'
  4. import BinaryFileHeader from './binary-file-header'
  5. import BinaryFileImage from './binary-file-image'
  6. import BinaryFileText from './binary-file-text'
  7. import Icon from '../../../shared/components/icon'
  8. const imageExtensions = ['png', 'jpg', 'jpeg', 'gif']
  9. const textExtensions = window.ExposedSettings.textExtensions
  10. export default function BinaryFile({ file, storeReferencesKeys }) {
  11. const [contentLoading, setContentLoading] = useState(true)
  12. const [hasError, setHasError] = useState(false)
  13. const { t } = useTranslation()
  14. const extension = file.name.split('.').pop().toLowerCase()
  15. const isUnpreviewableFile =
  16. !imageExtensions.includes(extension) && !textExtensions.includes(extension)
  17. function handleLoading() {
  18. if (contentLoading) {
  19. setContentLoading(false)
  20. }
  21. }
  22. function handleError() {
  23. if (!hasError) {
  24. setContentLoading(false)
  25. setHasError(true)
  26. }
  27. }
  28. const content = (
  29. <>
  30. <BinaryFileHeader file={file} storeReferencesKeys={storeReferencesKeys} />
  31. {imageExtensions.includes(extension) && (
  32. <BinaryFileImage
  33. fileName={file.name}
  34. fileId={file.id}
  35. onLoad={handleLoading}
  36. onError={handleError}
  37. />
  38. )}
  39. {textExtensions.includes(extension) && (
  40. <BinaryFileText
  41. file={file}
  42. onLoad={handleLoading}
  43. onError={handleError}
  44. />
  45. )}
  46. </>
  47. )
  48. return (
  49. <div className="binary-file full-size">
  50. {!hasError && content}
  51. {!isUnpreviewableFile && contentLoading && <BinaryFileLoadingIndicator />}
  52. {(isUnpreviewableFile || hasError) && (
  53. <p className="no-preview">{t('no_preview_available')}</p>
  54. )}
  55. </div>
  56. )
  57. }
  58. function BinaryFileLoadingIndicator() {
  59. const { t } = useTranslation()
  60. return (
  61. <div className="loading-panel loading-panel-binary-files">
  62. <span>
  63. <Icon type="refresh" modifier="spin" />
  64. &nbsp;&nbsp;{t('loading')}…
  65. </span>
  66. </div>
  67. )
  68. }
  69. BinaryFile.propTypes = {
  70. file: PropTypes.shape({
  71. id: PropTypes.string,
  72. name: PropTypes.string,
  73. }).isRequired,
  74. storeReferencesKeys: PropTypes.func.isRequired,
  75. }