overleaf/services/web/frontend/js/features/history/utils/auto-select-file.ts
Tim Down 66dc566752 Merge pull request #13039 from overleaf/td-history-auto-select-file-ignore-binary
History migration: Ignore binary files when auto-selecting file to display in history view

GitOrigin-RevId: 7d2a314cdb3d54e4e2292a95e7633e3829ea931f
2023-05-26 08:04:29 +00:00

126 lines
3.2 KiB
TypeScript

import type { Nullable } from '../../../../../types/utils'
import type { FileDiff } from '../services/types/file'
import type { FileOperation } from '../services/types/file-operation'
import type { LoadedUpdate, Version } from '../services/types/update'
import { fileFinalPathname, isFileEditable } from './file-diff'
type FileWithOps = {
pathname: FileDiff['pathname']
editable: boolean
operation: FileOperation
}
function getFilesWithOps(
files: FileDiff[],
toV: Version,
comparing: boolean,
updateForToV: LoadedUpdate | undefined
): FileWithOps[] {
if (toV && !comparing) {
const filesWithOps: FileWithOps[] = []
if (updateForToV) {
const filesByPathname = new Map<string, FileDiff>()
for (const file of files) {
const pathname = fileFinalPathname(file)
filesByPathname.set(pathname, file)
}
const isEditable = (pathname: string) => {
const fileDiff = filesByPathname.get(pathname)
if (!fileDiff) {
return false
}
return isFileEditable(fileDiff)
}
for (const pathname of updateForToV.pathnames) {
filesWithOps.push({
pathname,
editable: isEditable(pathname),
operation: 'edited',
})
}
for (const op of updateForToV.project_ops) {
let pathAndOp: Nullable<Pick<FileWithOps, 'pathname' | 'operation'>> =
null
if (op.add) {
pathAndOp = {
pathname: op.add.pathname,
operation: 'added',
}
} else if (op.remove) {
pathAndOp = {
pathname: op.remove.pathname,
operation: 'removed',
}
} else if (op.rename) {
pathAndOp = {
pathname: op.rename.newPathname,
operation: 'renamed',
}
}
if (pathAndOp !== null) {
filesWithOps.push({
editable: isEditable(pathAndOp.pathname),
...pathAndOp,
})
}
}
}
return filesWithOps
} else {
const filesWithOps = files.reduce((curFilesWithOps, file) => {
if ('operation' in file) {
curFilesWithOps.push({
pathname: file.pathname,
editable: isFileEditable(file),
operation: file.operation,
})
}
return curFilesWithOps
}, <FileWithOps[]>[])
return filesWithOps
}
}
const orderedOpTypes: FileOperation[] = [
'edited',
'added',
'renamed',
'removed',
]
export function autoSelectFile(
files: FileDiff[],
toV: Version,
comparing: boolean,
updateForToV: LoadedUpdate | undefined
): FileDiff {
const filesWithOps = getFilesWithOps(files, toV, comparing, updateForToV)
for (const opType of orderedOpTypes) {
const fileWithMatchingOpType = filesWithOps.find(
file => file.operation === opType && file.editable
)
if (fileWithMatchingOpType) {
const fileToSelect = files.find(
file => fileFinalPathname(file) === fileWithMatchingOpType.pathname
)
if (fileToSelect) {
return fileToSelect
}
}
}
return (
files.find(file => /main\.tex$/.test(file.pathname)) ||
files.find(file => /\.tex$/.test(file.pathname)) ||
files[0]
)
}