use-log-events.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import { useCallback } from 'react'
  2. import { useLayoutContext } from '@/shared/context/layout-context'
  3. import { useEditorContext } from '@/shared/context/editor-context'
  4. import useEventListener from '@/shared/hooks/use-event-listener'
  5. import { useIsNewEditorEnabled } from '@/features/ide-redesign/utils/new-editor-utils'
  6. function scrollIntoView(element: Element) {
  7. setTimeout(() => {
  8. element.scrollIntoView({
  9. block: 'start',
  10. inline: 'nearest',
  11. })
  12. })
  13. }
  14. /**
  15. * This hook adds an event listener for events dispatched from the editor to the compile logs pane
  16. */
  17. export const useLogEvents = (setShowLogs: (show: boolean) => void) => {
  18. const { pdfLayout, setView } = useLayoutContext()
  19. const newEditor = useIsNewEditorEnabled()
  20. const { hasPremiumSuggestion } = useEditorContext()
  21. const selectLogOldLogs = useCallback((id: string, suggestFix: boolean) => {
  22. window.setTimeout(() => {
  23. const element = document.querySelector(
  24. `.log-entry[data-log-entry-id="${id}"]`
  25. )
  26. if (element) {
  27. scrollIntoView(element)
  28. if (suggestFix) {
  29. // if they are paywalled, click that instead
  30. const paywall = document.querySelector<HTMLButtonElement>(
  31. 'button[data-action="assistant-paywall-show"]'
  32. )
  33. if (paywall) {
  34. scrollIntoView(paywall)
  35. paywall.click()
  36. } else {
  37. element
  38. .querySelector<HTMLButtonElement>(
  39. 'button[data-action="suggest-fix"]'
  40. )
  41. ?.click()
  42. }
  43. }
  44. }
  45. })
  46. }, [])
  47. const selectLogNewLogs = useCallback(
  48. (
  49. id: string,
  50. suggestFix: boolean,
  51. showPaywallIfOutOfSuggestions: boolean
  52. ) => {
  53. window.setTimeout(() => {
  54. const logEntry = document.querySelector(
  55. `.log-entry[data-log-entry-id="${id}"]`
  56. )
  57. if (logEntry) {
  58. scrollIntoView(logEntry)
  59. const expandCollapseButton =
  60. logEntry.querySelector<HTMLButtonElement>(
  61. 'button[data-action="expand-collapse"]'
  62. )
  63. const collapsed = expandCollapseButton?.dataset.collapsed === 'true'
  64. if (collapsed) {
  65. expandCollapseButton.click()
  66. }
  67. if (suggestFix) {
  68. if (hasPremiumSuggestion) {
  69. logEntry
  70. .querySelector<HTMLButtonElement>(
  71. 'button[data-action="suggest-fix"]'
  72. )
  73. ?.click()
  74. } else if (showPaywallIfOutOfSuggestions) {
  75. window.dispatchEvent(
  76. new CustomEvent('aiAssist:showPaywall', {
  77. detail: { origin: 'suggest-fix' },
  78. })
  79. )
  80. }
  81. }
  82. }
  83. })
  84. },
  85. [hasPremiumSuggestion]
  86. )
  87. const openLogs = useCallback(() => {
  88. setShowLogs(true)
  89. if (pdfLayout === 'flat') {
  90. setView('pdf')
  91. }
  92. }, [pdfLayout, setView, setShowLogs])
  93. const handleViewCompileLogEntryEvent = useCallback(
  94. (event: Event) => {
  95. const { id, suggestFix, showPaywallIfOutOfSuggestions } = (
  96. event as CustomEvent<{
  97. id: string
  98. suggestFix?: boolean
  99. showPaywallIfOutOfSuggestions?: boolean
  100. }>
  101. ).detail
  102. openLogs()
  103. if (newEditor) {
  104. selectLogNewLogs(
  105. id,
  106. Boolean(suggestFix),
  107. Boolean(showPaywallIfOutOfSuggestions)
  108. )
  109. } else {
  110. selectLogOldLogs(id, Boolean(suggestFix))
  111. }
  112. },
  113. [openLogs, selectLogNewLogs, selectLogOldLogs, newEditor]
  114. )
  115. useEventListener(
  116. 'editor:view-compile-log-entry',
  117. handleViewCompileLogEntryEvent
  118. )
  119. }