diff-view.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import { useEffect } 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. let diff: Diff | null
  51. if (!data?.diff) {
  52. diff = null
  53. } else if ('binary' in data.diff) {
  54. diff = { binary: true }
  55. } else {
  56. diff = {
  57. binary: false,
  58. docDiff: highlightsFromDiffResponse(data.diff, t),
  59. }
  60. }
  61. return (
  62. <div className="doc-panel">
  63. <div className="history-header toolbar-container">
  64. <Toolbar diff={diff} selection={selection} />
  65. </div>
  66. <div className="doc-container">
  67. <Main diff={diff} isLoading={isLoading || loadingFileDiffs} />
  68. </div>
  69. </div>
  70. )
  71. }
  72. export default DiffView