overleaf/services/web/frontend/js/features/file-view/components/file-view.jsx

91 lines
2.4 KiB
React
Raw Normal View History

import { useState, useCallback } from 'react'
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import FileViewHeader from './file-view-header'
import FileViewImage from './file-view-image'
import FileViewPdf from './file-view-pdf'
import FileViewText from './file-view-text'
[web] Migrate the file view to Bootstrap 5 (#20765) * [web] Remove unnecessary divs around `fileInfo` * [web] Add file-view SCSS style * [web] Simplify `TPRFileViewInfo` * [web] Add div for action buttons * [web] Misc. simplifications * [web] Add Overleaf logo in bg when selecting multiple files * [web] Add message when multiple files are selected * [web] Add .full-size class * [web] Import styles from LESS file * [web] Update icons, use MaterialIcon * [web] Use OLButton * [web] Add missing space between icons and text * [web] Adjust margins * [web] Fix alert button * [web] Update Alerts * [web] Update `FileViewLoadingIndicator` * [web] Fix test "shows a loading indicator..." This was failing because `LoadingSpinner` is shown after a setTimeout. Maybe we can skip this setTimeout when delay==0 ? * [web] Remove Row/Col around error notifications * [web] Replace `!!` by `Boolean` Co-authored-by: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> * [web] Use `alert` class in BS3 only Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com> * [web] Update "Go to settings" to OLButton Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com> * [web] Use `BootstrapVersionSwitcher` instead of `isBootstrap5` Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com> * [web] Align Alert content to the left in BS5 * [web] Remove `leadingIcon` on Refresh buttons * [web] Make the download link be an OLButton * [web] Set `tpr-refresh-error` in BS3 only Co-authored-by: Rebeka Dekany <50901361+rebekadekany@users.noreply.github.com> * [web] Use `var(--white);` instead of `white` Co-authored-by: Rebeka <rebeka.dekany@overleaf.com> * [web] Update OLButton size (small -> sm) --------- Co-authored-by: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com> Co-authored-by: Rebeka Dekany <50901361+rebekadekany@users.noreply.github.com> Co-authored-by: Rebeka <rebeka.dekany@overleaf.com> GitOrigin-RevId: 04f369c0f1a53d47619a1570648ee58de5050751
2024-10-10 03:38:28 -04:00
import LoadingSpinner from '@/shared/components/loading-spinner'
import getMeta from '@/utils/meta'
const imageExtensions = ['png', 'jpg', 'jpeg', 'gif']
export default function FileView({ file }) {
const [contentLoading, setContentLoading] = useState(true)
const [hasError, setHasError] = useState(false)
const { t } = useTranslation()
const { textExtensions, editableFilenames } = getMeta('ol-ExposedSettings')
const extension = file.name.split('.').pop().toLowerCase()
const isEditableTextFile =
textExtensions.includes(extension) ||
editableFilenames.includes(file.name.toLowerCase())
const isImageFile = imageExtensions.includes(extension)
const isPdfFile = extension === 'pdf'
const isUnpreviewableFile = !isEditableTextFile && !isImageFile && !isPdfFile
const handleLoad = useCallback(() => {
setContentLoading(false)
}, [])
const handleError = useCallback(() => {
if (!hasError) {
setContentLoading(false)
setHasError(true)
}
}, [hasError])
const content = (
<>
<FileViewHeader file={file} />
{isImageFile && (
<FileViewImage file={file} onLoad={handleLoad} onError={handleError} />
)}
{isEditableTextFile && (
<FileViewText file={file} onLoad={handleLoad} onError={handleError} />
)}
{isPdfFile && (
<FileViewPdf
fileId={file.id}
onLoad={handleLoad}
onError={handleError}
/>
)}
</>
)
return (
<div className="file-view full-size">
{!hasError && content}
{!isUnpreviewableFile && contentLoading && <FileViewLoadingIndicator />}
{(isUnpreviewableFile || hasError) && (
<p className="no-preview">{t('no_preview_available')}</p>
)}
</div>
)
}
function FileViewLoadingIndicator() {
return (
[web] Migrate the file view to Bootstrap 5 (#20765) * [web] Remove unnecessary divs around `fileInfo` * [web] Add file-view SCSS style * [web] Simplify `TPRFileViewInfo` * [web] Add div for action buttons * [web] Misc. simplifications * [web] Add Overleaf logo in bg when selecting multiple files * [web] Add message when multiple files are selected * [web] Add .full-size class * [web] Import styles from LESS file * [web] Update icons, use MaterialIcon * [web] Use OLButton * [web] Add missing space between icons and text * [web] Adjust margins * [web] Fix alert button * [web] Update Alerts * [web] Update `FileViewLoadingIndicator` * [web] Fix test "shows a loading indicator..." This was failing because `LoadingSpinner` is shown after a setTimeout. Maybe we can skip this setTimeout when delay==0 ? * [web] Remove Row/Col around error notifications * [web] Replace `!!` by `Boolean` Co-authored-by: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> * [web] Use `alert` class in BS3 only Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com> * [web] Update "Go to settings" to OLButton Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com> * [web] Use `BootstrapVersionSwitcher` instead of `isBootstrap5` Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com> * [web] Align Alert content to the left in BS5 * [web] Remove `leadingIcon` on Refresh buttons * [web] Make the download link be an OLButton * [web] Set `tpr-refresh-error` in BS3 only Co-authored-by: Rebeka Dekany <50901361+rebekadekany@users.noreply.github.com> * [web] Use `var(--white);` instead of `white` Co-authored-by: Rebeka <rebeka.dekany@overleaf.com> * [web] Update OLButton size (small -> sm) --------- Co-authored-by: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com> Co-authored-by: Rebeka Dekany <50901361+rebekadekany@users.noreply.github.com> Co-authored-by: Rebeka <rebeka.dekany@overleaf.com> GitOrigin-RevId: 04f369c0f1a53d47619a1570648ee58de5050751
2024-10-10 03:38:28 -04:00
<div
className="loading-panel loading-panel-file-view"
data-testid="loading-panel-file-view"
>
<LoadingSpinner />
</div>
)
}
FileView.propTypes = {
file: PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string,
hash: PropTypes.string,
}).isRequired,
}