Merge pull request #26100 from overleaf/dp-compile-timeout-paywall

Add compile timeout paywall to new editor

GitOrigin-RevId: 9742ae67b4103c72cc9d87852801ae8751f85d6d
This commit is contained in:
David
2025-06-05 08:05:20 +00:00
committed by Copybot
parent 08316442cf
commit a8a21e05af
4 changed files with 100 additions and 29 deletions
@@ -287,6 +287,8 @@
"compile_error_entry_description": "",
"compile_error_handling": "",
"compile_larger_projects": "",
"compile_limit_reached": "",
"compile_limit_upgrade_prompt": "",
"compile_mode": "",
"compile_terminated_by_user": "",
"compiler": "",
@@ -5,31 +5,37 @@ import { useRailContext } from '../../contexts/rail-context'
import { usePdfPreviewContext } from '@/features/pdf-preview/components/pdf-preview-provider'
import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context'
import { useIsNewEditorEnabled } from '../../utils/new-editor-utils'
import { upgradePlan } from '@/main/account-upgrade'
import classNames from 'classnames'
function PdfErrorState() {
const { loadingError } = usePdfPreviewContext()
// TODO ide-redesign-cleanup: rename showLogs to something else and check usages
const { showLogs } = useCompileContext()
const { t } = useTranslation()
const { openTab: openRailTab } = useRailContext()
const { hasShortCompileTimeout, error, showLogs } = useCompileContext()
const newEditor = useIsNewEditorEnabled()
if (!newEditor || (!loadingError && !showLogs)) {
return null
}
if (hasShortCompileTimeout && error === 'timedout') {
return <CompileTimeoutErrorState />
}
return <GeneralErrorState />
}
const GeneralErrorState = () => {
const { t } = useTranslation()
const { openTab: openRailTab } = useRailContext()
return (
<div className="pdf-error-state">
<div className="pdf-error-state-top-section">
<div className="pdf-error-state-warning-icon">
<MaterialIcon type="warning" />
</div>
<div className="pdf-error-state-text">
<p className="pdf-error-state-label">{t('pdf_couldnt_compile')}</p>
<p className="pdf-error-state-description">
{t('we_are_unable_to_generate_the_pdf_at_this_time')}
</p>
</div>
<ErrorState
title={t('pdf_couldnt_compile')}
description={t('we_are_unable_to_generate_the_pdf_at_this_time')}
iconType="warning"
iconClassName="pdf-error-state-warning-icon"
actions={
<OLButton
variant="secondary"
size="sm"
@@ -39,20 +45,74 @@ function PdfErrorState() {
>
{t('check_logs')}
</OLButton>
</div>
<div className="pdf-error-state-info-box">
<div className="pdf-error-state-info-box-title">
<MaterialIcon type="info" unfilled />
{t('why_might_this_happen')}
}
extraContent={
<div className="pdf-error-state-info-box">
<div className="pdf-error-state-info-box-title">
<MaterialIcon type="info" unfilled />
{t('why_might_this_happen')}
</div>
<ul className="pdf-error-state-info-box-text">
<li>{t('there_is_an_unrecoverable_latex_error')}</li>
<li>{t('the_document_environment_contains_no_content')}</li>
<li>{t('this_project_contains_a_file_called_output')}</li>
</ul>
</div>
<ul className="pdf-error-state-info-box-text">
<li>{t('there_is_an_unrecoverable_latex_error')}</li>
<li>{t('the_document_environment_contains_no_content')}</li>
<li>{t('this_project_contains_a_file_called_output')}</li>
</ul>
</div>
</div>
}
/>
)
}
const CompileTimeoutErrorState = () => {
const { t } = useTranslation()
return (
<ErrorState
title={t('compile_limit_reached')}
description={t('compile_limit_upgrade_prompt')}
iconType="running_with_errors"
actions={
<OLButton
variant="premium"
size="sm"
onClick={() => upgradePlan('compile-timeout')}
>
{t('upgrade')}
</OLButton>
}
/>
)
}
const ErrorState = ({
title,
description,
iconType,
actions,
iconClassName,
extraContent,
}: {
title: string
description: string
iconType: string
actions: React.ReactNode
iconClassName?: string
extraContent?: React.ReactNode
}) => {
return (
<div className="pdf-error-state">
<div className="pdf-error-state-top-section">
<div className={classNames('pdf-error-state-icon', iconClassName)}>
<MaterialIcon type={iconType} />
</div>
<div className="pdf-error-state-text">
<p className="pdf-error-state-label">{title}</p>
<p className="pdf-error-state-description">{description}</p>
</div>
{actions}
</div>
{extraContent}
</div>
)
}
export default PdfErrorState
@@ -33,9 +33,7 @@
padding: 0 var(--spacing-09) var(--spacing-09) var(--spacing-09);
}
.pdf-error-state-warning-icon {
background-color: var(--bg-danger-03);
color: var(--content-danger);
.pdf-error-state-icon {
width: 80px;
height: 80px;
display: flex;
@@ -43,6 +41,15 @@
justify-content: center;
border-radius: 100%;
.material-symbols {
font-size: 80px;
}
}
.pdf-error-state-warning-icon {
background-color: var(--bg-danger-03);
color: var(--content-danger);
.material-symbols {
font-size: 32px;
}