2023-10-04 15:36:34 -04:00
|
|
|
import {
|
|
|
|
type Dispatch,
|
|
|
|
type SetStateAction,
|
2023-10-25 14:18:37 -04:00
|
|
|
type ElementType,
|
2023-10-04 15:36:34 -04:00
|
|
|
useCallback,
|
|
|
|
useState,
|
|
|
|
} from 'react'
|
|
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
import Icon from '@/shared/components/icon'
|
|
|
|
import { postJSON } from '@/infrastructure/fetch-json'
|
|
|
|
import { useProjectContext } from '@/shared/context/project-context'
|
|
|
|
import useAbortController from '@/shared/hooks/use-abort-controller'
|
2023-10-25 14:18:37 -04:00
|
|
|
import type { BinaryFile } from '../types/binary-file'
|
2023-10-04 15:36:34 -04:00
|
|
|
import { Nullable } from '../../../../../types/utils'
|
2023-10-25 14:18:37 -04:00
|
|
|
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
2023-10-04 15:36:34 -04:00
|
|
|
|
|
|
|
type FileViewRefreshButtonProps = {
|
|
|
|
setRefreshError: Dispatch<SetStateAction<Nullable<string>>>
|
|
|
|
file: BinaryFile
|
|
|
|
}
|
|
|
|
|
2023-10-25 14:18:37 -04:00
|
|
|
const tprFileViewRefreshButton = importOverleafModules(
|
|
|
|
'tprFileViewRefreshButton'
|
|
|
|
) as {
|
|
|
|
import: { TPRFileViewRefreshButton: ElementType }
|
|
|
|
path: string
|
|
|
|
}[]
|
|
|
|
|
2023-10-04 15:36:34 -04:00
|
|
|
export default function FileViewRefreshButton({
|
|
|
|
setRefreshError,
|
|
|
|
file,
|
|
|
|
}: FileViewRefreshButtonProps) {
|
2023-10-25 14:18:37 -04:00
|
|
|
const { _id: projectId } = useProjectContext()
|
2023-10-04 15:36:34 -04:00
|
|
|
const { signal } = useAbortController()
|
|
|
|
const [refreshing, setRefreshing] = useState(false)
|
|
|
|
|
2023-10-25 14:18:37 -04:00
|
|
|
const refreshFile = useCallback(
|
|
|
|
(isTPR: Nullable<boolean>) => {
|
|
|
|
setRefreshing(true)
|
|
|
|
// Replacement of the file handled by the file tree
|
|
|
|
window.expectingLinkedFileRefreshedSocketFor = file.name
|
|
|
|
const body = {
|
|
|
|
shouldReindexReferences: isTPR || /\.bib$/.test(file.name),
|
|
|
|
}
|
|
|
|
postJSON(`/project/${projectId}/linked_file/${file.id}/refresh`, {
|
|
|
|
signal,
|
|
|
|
body,
|
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
setRefreshing(false)
|
|
|
|
})
|
|
|
|
.catch(err => {
|
|
|
|
setRefreshing(false)
|
|
|
|
setRefreshError(err.data?.message || err.message)
|
|
|
|
})
|
|
|
|
},
|
|
|
|
[file, projectId, signal, setRefreshError]
|
|
|
|
)
|
2023-10-04 15:36:34 -04:00
|
|
|
|
2023-10-25 14:18:37 -04:00
|
|
|
if (tprFileViewRefreshButton.length > 0) {
|
|
|
|
return tprFileViewRefreshButton.map(
|
|
|
|
({ import: { TPRFileViewRefreshButton }, path }) => (
|
|
|
|
<TPRFileViewRefreshButton
|
|
|
|
key={path}
|
|
|
|
file={file}
|
|
|
|
refreshFile={refreshFile}
|
|
|
|
refreshing={refreshing}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
)[0]
|
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
<FileViewRefreshButtonDefault
|
|
|
|
refreshFile={refreshFile}
|
|
|
|
refreshing={refreshing}
|
|
|
|
/>
|
|
|
|
)
|
2023-10-04 15:36:34 -04:00
|
|
|
}
|
2023-10-25 14:18:37 -04:00
|
|
|
}
|
2023-10-04 15:36:34 -04:00
|
|
|
|
2023-10-25 14:18:37 -04:00
|
|
|
type FileViewRefreshButtonDefaultProps = {
|
|
|
|
refreshFile: (isTPR: Nullable<boolean>) => void
|
|
|
|
refreshing: boolean
|
|
|
|
}
|
2023-10-04 15:36:34 -04:00
|
|
|
|
2023-10-25 14:18:37 -04:00
|
|
|
function FileViewRefreshButtonDefault({
|
|
|
|
refreshFile,
|
|
|
|
refreshing,
|
|
|
|
}: FileViewRefreshButtonDefaultProps) {
|
|
|
|
const { t } = useTranslation()
|
2023-10-04 15:36:34 -04:00
|
|
|
|
|
|
|
return (
|
|
|
|
<button
|
2023-10-25 14:18:37 -04:00
|
|
|
className="btn btn-primary"
|
|
|
|
onClick={() => refreshFile(null)}
|
|
|
|
disabled={refreshing}
|
2023-10-04 15:36:34 -04:00
|
|
|
>
|
|
|
|
<Icon type="refresh" spin={refreshing} fw />
|
|
|
|
<span>{refreshing ? `${t('refreshing')}…` : t('refresh')}</span>
|
|
|
|
</button>
|
|
|
|
)
|
|
|
|
}
|