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

GitOrigin-RevId: 88c6658ff0d11fdb43cef19c48b542a3b2206666
This commit is contained in:
Alf Eaton
2025-04-28 08:05:42 +00:00
committed by Copybot
parent c6ac06b51c
commit c732a02b38
7 changed files with 85 additions and 45 deletions
@@ -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' ||
@@ -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) {
@@ -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(
@@ -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',
},
})
)
}
@@ -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
@@ -83,10 +83,6 @@
margin-left: 20px;
}
#synctex-more-info-button {
margin-left: 20px;
}
#ide-body {
background-color: @pdf-bg;
.full-size;
@@ -442,3 +442,8 @@
top: var(--spacing-10);
z-index: 1;
}
.synctex-error-toast-content {
display: flex;
gap: 20px;
}