use-convert-project.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import { FetchError, getJSON } from '@/infrastructure/fetch-json'
  2. import { useLocation } from '@/shared/hooks/use-location'
  3. import { debugConsole } from '@/utils/debugging'
  4. import { useProjectContext } from '@/shared/context/project-context'
  5. import { useCallback } from 'react'
  6. import {
  7. hideExportDocumentError,
  8. hidePreparingExportToast,
  9. showExportDocumentError,
  10. showExportDocumentSuccess,
  11. showPreparingExportToast,
  12. } from '../components/toolbar/export-document-toasts'
  13. import { RootDocInfo } from '@/shared/hooks/use-root-doc'
  14. import { OpenDocuments } from '../editor/open-documents'
  15. const SLOW_CONVERSION_THRESHOLD = 2000
  16. export default function useConvertProject(
  17. type: 'docx' | 'markdown',
  18. openDocs: OpenDocuments,
  19. getRootDocInfo: () => RootDocInfo
  20. ) {
  21. const { projectId } = useProjectContext()
  22. const location = useLocation()
  23. return useCallback(async () => {
  24. let handle: string | undefined
  25. const toastTimer = setTimeout(() => {
  26. handle = showPreparingExportToast()
  27. }, SLOW_CONVERSION_THRESHOLD)
  28. const hidePreparingToast = () => {
  29. clearTimeout(toastTimer)
  30. if (handle) hidePreparingExportToast(handle)
  31. }
  32. const url = new URL(window.location.origin)
  33. url.pathname = `/project/${projectId}/download/conversion/${type}`
  34. url.searchParams.set('responseFormat', 'json')
  35. const { rootResourcePath } = getRootDocInfo()
  36. url.searchParams.set('rootResourcePath', rootResourcePath)
  37. hideExportDocumentError()
  38. try {
  39. await openDocs.awaitBufferedOps(AbortSignal.timeout(10_000))
  40. const response = await getJSON(url.href)
  41. hidePreparingToast()
  42. const { downloadUrl } = response
  43. if (downloadUrl) {
  44. const url = new URL(downloadUrl, window.location.origin)
  45. location.assign(url.toString())
  46. showExportDocumentSuccess(type)
  47. } else {
  48. showExportDocumentError()
  49. }
  50. } catch (error) {
  51. hidePreparingToast()
  52. let errorMessage
  53. if (
  54. error instanceof FetchError &&
  55. error.response?.status === 422 &&
  56. error.data?.error
  57. ) {
  58. errorMessage = error.data.error
  59. }
  60. showExportDocumentError(errorMessage)
  61. debugConsole.error(error)
  62. }
  63. }, [projectId, type, getRootDocInfo, openDocs, location])
  64. }