Sfoglia il codice sorgente

Use toast notifications for SyncTeX errors and handle missing file errors (#24579)

GitOrigin-RevId: 88c6658ff0d11fdb43cef19c48b542a3b2206666
Alf Eaton 1 anno fa
parent
commit
c732a02b38

+ 0 - 22
services/web/frontend/js/features/ide-react/components/alerts/alerts.tsx

@@ -2,11 +2,9 @@ import { useTranslation } from 'react-i18next'
 import { LostConnectionAlert } from './lost-connection-alert'
 import { useConnectionContext } from '@/features/ide-react/context/connection-context'
 import { debugging } from '@/utils/debugging'
-import useScopeValue from '@/shared/hooks/use-scope-value'
 import { createPortal } from 'react-dom'
 import { useGlobalAlertsContainer } from '@/features/ide-react/context/global-alerts-context'
 import OLNotification from '@/features/ui/components/ol/ol-notification'
-import OLButton from '@/features/ui/components/ol/ol-button'
 
 export function Alerts() {
   const { t } = useTranslation()
@@ -19,8 +17,6 @@ export function Alerts() {
   } = useConnectionContext()
   const globalAlertsContainer = useGlobalAlertsContainer()
 
-  const [synctexError] = useScopeValue('sync_tex_error')
-
   if (!globalAlertsContainer) {
     return null
   }
@@ -50,24 +46,6 @@ export function Alerts() {
         />
       ) : null}
 
-      {synctexError ? (
-        <OLNotification
-          type="warning"
-          content={<strong>{t('synctex_failed')}</strong>}
-          action={
-            <OLButton
-              href="/learn/how-to/SyncTeX_Errors"
-              target="_blank"
-              id="synctex-more-info-button"
-              variant="secondary"
-              size="sm"
-            >
-              {t('more_info')}
-            </OLButton>
-          }
-        />
-      ) : null}
-
       {connectionState.inactiveDisconnect ||
       (connectionState.readyState === WebSocket.CLOSED &&
         (connectionState.error === 'rate-limited' ||

+ 0 - 1
services/web/frontend/js/features/ide-react/context/ide-react-context.tsx

@@ -41,7 +41,6 @@ export const IdeReactContext = createContext<IdeReactContextValue | undefined>(
 
 function populateIdeReactScope(store: ReactScopeValueStore) {
   store.set('settings', {})
-  store.set('sync_tex_error', false)
 }
 
 function populateProjectScope(store: ReactScopeValueStore) {

+ 7 - 18
services/web/frontend/js/features/pdf-preview/components/pdf-synctex-controls.tsx

@@ -4,7 +4,6 @@ import { useProjectContext } from '../../../shared/context/project-context'
 import { getJSON } from '../../../infrastructure/fetch-json'
 import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
 import { useLayoutContext } from '../../../shared/context/layout-context'
-import useScopeValue from '../../../shared/hooks/use-scope-value'
 import { useTranslation } from 'react-i18next'
 import useIsMounted from '../../../shared/hooks/use-is-mounted'
 import useAbortController from '../../../shared/hooks/use-abort-controller'
@@ -26,6 +25,7 @@ import { CursorPosition } from '@/features/ide-react/types/cursor-position'
 import { isValidTeXFile } from '@/main/is-valid-tex-file'
 import { PdfScrollPosition } from '@/shared/hooks/use-pdf-scroll-position'
 import { Placement } from 'react-bootstrap-5/types'
+import { showFileErrorToast } from '@/features/pdf-preview/components/synctex-toasts'
 
 const GoToCodeButton = memo(function GoToCodeButton({
   syncToCode,
@@ -183,8 +183,6 @@ function PdfSynctexControls() {
     'detached'
   )
 
-  const [, setSynctexError] = useScopeValue('sync_tex_error')
-
   const getCurrentFilePath = useCallback(() => {
     const docId = getCurrentDocumentId()
 
@@ -212,25 +210,16 @@ function PdfSynctexControls() {
     (file, line) => {
       if (file) {
         const doc = findEntityByPath(file)?.entity
-        if (!doc) {
-          debugConsole.warn(`Document with path ${file} not found`)
+        if (doc) {
+          openDocWithId(doc._id, {
+            gotoLine: line,
+          })
           return
         }
-
-        openDocWithId(doc._id, {
-          gotoLine: line,
-        })
-      } else {
-        setSynctexError(true)
-
-        window.setTimeout(() => {
-          if (isMounted.current) {
-            setSynctexError(false)
-          }
-        }, 4000)
       }
+      showFileErrorToast()
     },
-    [findEntityByPath, openDocWithId, isMounted, setSynctexError]
+    [findEntityByPath, openDocWithId]
   )
 
   const goToPdfLocation = useCallback(

+ 47 - 0
services/web/frontend/js/features/pdf-preview/components/synctex-toasts.tsx

@@ -0,0 +1,47 @@
+import { GlobalToastGeneratorEntry } from '@/features/ide-react/components/global-toasts'
+import { useTranslation } from 'react-i18next'
+import OLButton from '@/features/ui/components/ol/ol-button'
+
+export const SynctexFileErrorToast = () => {
+  const { t } = useTranslation()
+
+  return (
+    <div className="synctex-error-toast-content">
+      <span>{t('synctex_failed')}</span>
+
+      <OLButton
+        href="/learn/how-to/SyncTeX_Errors"
+        target="_blank"
+        variant="secondary"
+        size="sm"
+      >
+        {t('more_info')}
+      </OLButton>
+    </div>
+  )
+}
+
+const generators: GlobalToastGeneratorEntry[] = [
+  {
+    key: 'synctex:file-error',
+    generator: () => ({
+      content: <SynctexFileErrorToast />,
+      type: 'warning',
+      autoHide: true,
+      delay: 4000,
+      isDismissible: true,
+    }),
+  },
+]
+
+export default generators
+
+export const showFileErrorToast = () => {
+  window.dispatchEvent(
+    new CustomEvent('ide:show-toast', {
+      detail: {
+        key: 'synctex:file-error',
+      },
+    })
+  )
+}

+ 26 - 0
services/web/frontend/stories/editor/synctex-toasts.stories.tsx

@@ -0,0 +1,26 @@
+import { Meta, StoryObj } from '@storybook/react'
+import { OLToast } from '@/features/ui/components/ol/ol-toast'
+import { SynctexFileErrorToast } from '@/features/pdf-preview/components/synctex-toasts'
+
+const meta = {
+  title: 'Editor/ Synctex File Error Toast',
+  component: SynctexFileErrorToast,
+  decorators: [
+    Story => (
+      <div style={{ width: 'fit-content' }}>
+        <OLToast type="warning" isDismissible content={<Story />} />
+      </div>
+    ),
+  ],
+} satisfies Meta<typeof SynctexFileErrorToast>
+
+export default meta
+type Story = StoryObj<typeof meta>
+
+export const WithoutFile = {
+  args: { data: {} },
+} satisfies Story
+
+export const WithFile = {
+  args: { data: { filePath: 'references.bbl' } },
+} satisfies Story

+ 0 - 4
services/web/frontend/stylesheets/app/editor.less

@@ -83,10 +83,6 @@
   margin-left: 20px;
 }
 
-#synctex-more-info-button {
-  margin-left: 20px;
-}
-
 #ide-body {
   background-color: @pdf-bg;
   .full-size;

+ 5 - 0
services/web/frontend/stylesheets/bootstrap-5/pages/editor/pdf.scss

@@ -442,3 +442,8 @@
   top: var(--spacing-10);
   z-index: 1;
 }
+
+.synctex-error-toast-content {
+  display: flex;
+  gap: 20px;
+}