diff-view.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { useEffect, useMemo } from 'react'
  2. import Toolbar from './toolbar/toolbar'
  3. import Main from './main'
  4. import { Diff, DocDiffResponse } from '../../services/types/doc'
  5. import { useHistoryContext } from '../../context/history-context'
  6. import { diffDoc } from '../../services/api'
  7. import { highlightsFromDiffResponse } from '../../utils/highlights-from-diff-response'
  8. import { useErrorHandler } from 'react-error-boundary'
  9. import useAsync from '../../../../shared/hooks/use-async'
  10. import { useTranslation } from 'react-i18next'
  11. function DiffView() {
  12. const { selection, projectId, loadingFileDiffs } = useHistoryContext()
  13. const { isLoading, data, runAsync } = useAsync<DocDiffResponse>()
  14. const { t } = useTranslation()
  15. const { updateRange, selectedFile } = selection
  16. const handleError = useErrorHandler()
  17. useEffect(() => {
  18. if (!updateRange || !selectedFile?.pathname || loadingFileDiffs) {
  19. return
  20. }
  21. const { fromV, toV } = updateRange
  22. let abortController: AbortController | null = new AbortController()
  23. runAsync(
  24. diffDoc(
  25. projectId,
  26. fromV,
  27. toV,
  28. selectedFile.pathname,
  29. abortController.signal
  30. )
  31. )
  32. .catch(handleError)
  33. .finally(() => {
  34. abortController = null
  35. })
  36. // Abort an existing request before starting a new one or on unmount
  37. return () => {
  38. if (abortController) {
  39. abortController.abort()
  40. }
  41. }
  42. }, [
  43. projectId,
  44. runAsync,
  45. updateRange,
  46. selectedFile,
  47. loadingFileDiffs,
  48. handleError,
  49. ])
  50. const diff = useMemo(() => {
  51. let diff: Diff | null
  52. if (!data?.diff) {
  53. diff = null
  54. } else if ('binary' in data.diff) {
  55. diff = { binary: true }
  56. } else {
  57. diff = {
  58. binary: false,
  59. docDiff: highlightsFromDiffResponse(data.diff, t),
  60. }
  61. }
  62. return diff
  63. }, [data, t])
  64. return (
  65. <div className="doc-panel">
  66. <div className="history-header toolbar-container">
  67. <Toolbar diff={diff} selection={selection} />
  68. </div>
  69. <div className="doc-container">
  70. <Main diff={diff} isLoading={isLoading || loadingFileDiffs} />
  71. </div>
  72. </div>
  73. )
  74. }
  75. export default DiffView