import { useState, type ElementType } from 'react' import PropTypes from 'prop-types' import { Trans, useTranslation } from 'react-i18next' import Icon from '../../../shared/components/icon' import { formatTime, relativeDate } from '../../utils/format-date' import { useEditorContext } from '../../../shared/context/editor-context' import { useProjectContext } from '../../../shared/context/project-context' import { Nullable } from '../../../../../types/utils' import importOverleafModules from '../../../../macros/import-overleaf-module.macro' import { LinkedFileIcon } from './file-view-icons' import { BinaryFile, hasProvider, LinkedFile } from '../types/binary-file' import FileViewRefreshButton from './file-view-refresh-button' import FileViewNotOriginalImporter from './file-view-not-original-importer' import FileViewRefreshError from './file-view-refresh-error' const tprLinkedFileInfo = importOverleafModules('tprLinkedFileInfo') as { import: { LinkedFileInfo: ElementType } path: string }[] const MAX_URL_LENGTH = 60 const FRONT_OF_URL_LENGTH = 35 const FILLER = '...' const TAIL_OF_URL_LENGTH = MAX_URL_LENGTH - FRONT_OF_URL_LENGTH - FILLER.length function shortenedUrl(url: string) { if (!url) { return } if (url.length > MAX_URL_LENGTH) { const front = url.slice(0, FRONT_OF_URL_LENGTH) const tail = url.slice(url.length - TAIL_OF_URL_LENGTH) return front + FILLER + tail } return url } type FileViewHeaderProps = { file: BinaryFile } export default function FileViewHeader({ file }: FileViewHeaderProps) { const { _id: projectId } = useProjectContext({ _id: PropTypes.string.isRequired, }) const { permissionsLevel } = useEditorContext({ permissionsLevel: PropTypes.string, }) const { t } = useTranslation() const [refreshError, setRefreshError] = useState>(null) let fileInfo if (file.linkedFileData) { if (hasProvider(file, 'url')) { fileInfo = (
) } else if (hasProvider(file, 'project_file')) { fileInfo = (
) } else if (hasProvider(file, 'project_output_file')) { fileInfo = (
) } } return (
{file.linkedFileData && fileInfo} {file.linkedFileData && tprLinkedFileInfo.map(({ import: { LinkedFileInfo }, path }) => ( ))} {file.linkedFileData && permissionsLevel !== 'readOnly' && ( )}     {t('download')} {file.linkedFileData && } {refreshError && ( )}
) } type UrlProviderProps = { file: LinkedFile<'url'> } function UrlProvider({ file }: UrlProviderProps) { return (

  ] } values={{ shortenedUrl: shortenedUrl(file.linkedFileData.url), formattedDate: formatTime(file.created), relativeDate: relativeDate(file.created), }} shouldUnescape tOptions={{ interpolation: { escapeValue: true } }} />

) } type ProjectFilePathProviderProps = { file: LinkedFile<'project_file'> } function ProjectFilePathProvider({ file }: ProjectFilePathProviderProps) { /* eslint-disable jsx-a11y/anchor-has-content, react/jsx-key */ return (

  ] : [ , ] } values={{ sourceEntityPath: file.linkedFileData.source_entity_path.slice(1), formattedDate: formatTime(file.created), relativeDate: relativeDate(file.created), }} shouldUnescape tOptions={{ interpolation: { escapeValue: true } }} />

/* esline-enable jsx-a11y/anchor-has-content, react/jsx-key */ ) } type ProjectOutputFileProviderProps = { file: LinkedFile<'project_output_file'> } function ProjectOutputFileProvider({ file }: ProjectOutputFileProviderProps) { return (

  ] : [ , ] } values={{ sourceOutputFilePath: file.linkedFileData.source_output_file_path, formattedDate: formatTime(file.created), relativeDate: relativeDate(file.created), }} shouldUnescape tOptions={{ interpolation: { escapeValue: true } }} />

) }