diff-view.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { useEffect, useState } from 'react'
  2. import Toolbar from './toolbar/toolbar'
  3. import Main from './main'
  4. import { Diff, DocDiffResponse } from '../../services/types/doc'
  5. import { Nullable } from '../../../../../../types/utils'
  6. import { useHistoryContext } from '../../context/history-context'
  7. import { diffDoc } from '../../services/api'
  8. import { highlightsFromDiffResponse } from '../../utils/highlights-from-diff-response'
  9. import useAsync from '../../../../shared/hooks/use-async'
  10. import ErrorMessage from '../error-message'
  11. function DiffView() {
  12. const [diff, setDiff] = useState<Nullable<Diff>>(null)
  13. const { selection, projectId } = useHistoryContext()
  14. const { isLoading, runAsync, error } = useAsync<DocDiffResponse>()
  15. const { updateRange, selectedFile } = selection
  16. useEffect(() => {
  17. if (!updateRange || !selectedFile?.pathname) {
  18. return
  19. }
  20. const { fromV, toV } = updateRange
  21. runAsync(diffDoc(projectId, fromV, toV, selectedFile.pathname))
  22. .then(data => {
  23. let diff: Diff | undefined
  24. if (!data?.diff) {
  25. setDiff(null)
  26. }
  27. if ('binary' in data.diff) {
  28. diff = { binary: true }
  29. } else {
  30. diff = {
  31. binary: false,
  32. docDiff: highlightsFromDiffResponse(data.diff),
  33. }
  34. }
  35. setDiff(diff)
  36. })
  37. .catch(console.error)
  38. }, [projectId, runAsync, updateRange, selectedFile])
  39. return (
  40. <div className="doc-panel">
  41. {error ? (
  42. <ErrorMessage />
  43. ) : (
  44. <>
  45. <div className="history-header toolbar-container">
  46. <Toolbar diff={diff} selection={selection} />
  47. </div>
  48. <div className="doc-container">
  49. <Main diff={diff} isLoading={isLoading} />
  50. </div>
  51. </>
  52. )}
  53. </div>
  54. )
  55. }
  56. export default DiffView