diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js index da08ac3c4f..90993d71f6 100644 --- a/services/web/config/settings.defaults.js +++ b/services/web/config/settings.defaults.js @@ -851,6 +851,7 @@ module.exports = { sourceEditorComponents: [], sourceEditorCompletionSources: [], sourceEditorSymbolPalette: [], + writefullEditorPromotion: [], langFeedbackLinkingWidgets: [], integrationLinkingWidgets: [], referenceLinkingWidgets: [], diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 684d15a157..ca3a3eea75 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -1448,8 +1448,11 @@ "work_offline": "", "work_with_non_overleaf_users": "", "writefull": "", - "writefull_how_to": "", + "writefull_learn_more": "", + "writefull_prompt_body": "", + "writefull_prompt_title": "", "writefull_settings_description": "", + "writefull_settings_instructions": "", "x_changes_in": "", "x_changes_in_plural": "", "x_price_for_first_month": "", diff --git a/services/web/frontend/js/features/settings/components/linking/enable-widget.tsx b/services/web/frontend/js/features/settings/components/linking/enable-widget.tsx index 998d7feda0..cfbfa1fcc0 100644 --- a/services/web/frontend/js/features/settings/components/linking/enable-widget.tsx +++ b/services/web/frontend/js/features/settings/components/linking/enable-widget.tsx @@ -12,6 +12,7 @@ type EnableWidgetProps = { title: string description: string helpPath: string + helpTextOverride?: string hasFeature?: boolean isPremiumFeature?: boolean statusIndicator?: ReactNode @@ -27,6 +28,7 @@ export function EnableWidget({ title, description, helpPath, + helpTextOverride, hasFeature, isPremiumFeature, statusIndicator, @@ -37,6 +39,7 @@ export function EnableWidget({ disabled, }: EnableWidgetProps) { const { t } = useTranslation() + const helpText = helpTextOverride || t('learn_more') return (
{description}{' '} - {t('learn_more')} + {helpText}
{children} diff --git a/services/web/frontend/js/features/source-editor/components/grammarly-advert.tsx b/services/web/frontend/js/features/source-editor/components/grammarly-advert.tsx index 003ccadbe7..c66cac0827 100644 --- a/services/web/frontend/js/features/source-editor/components/grammarly-advert.tsx +++ b/services/web/frontend/js/features/source-editor/components/grammarly-advert.tsx @@ -2,19 +2,12 @@ import { useCallback, useEffect, useState } from 'react' import MaterialIcon from '@/shared/components/material-icon' import * as eventTracking from '../../../infrastructure/event-tracking' import customLocalStorage from '../../../infrastructure/local-storage' -import grammarlyExtensionPresent from '../../../shared/utils/grammarly' +import useWaitForGrammarlyCheck from '@/shared/hooks/use-wait-for-grammarly-check' export default function GrammarlyAdvert() { const [show, setShow] = useState(false) - // grammarly can take some time to load, and wont tell us when they do... so we need to run the check after a bit of time - const [grammarlyInstalled, setGrammarlyInstalled] = useState(false) - useEffect(() => { - const timer = setTimeout( - () => setGrammarlyInstalled(grammarlyExtensionPresent()), - 5000 - ) - return () => clearTimeout(timer) - }, []) + // grammarly can take some time to load, we should assume its installed and hide until we know for sure + const grammarlyInstalled = useWaitForGrammarlyCheck({ initialState: false }) useEffect(() => { const hasDismissedGrammarlyAdvert = customLocalStorage.getItem( diff --git a/services/web/frontend/js/features/source-editor/components/source-editor.tsx b/services/web/frontend/js/features/source-editor/components/source-editor.tsx index d71f896687..84d60cdab6 100644 --- a/services/web/frontend/js/features/source-editor/components/source-editor.tsx +++ b/services/web/frontend/js/features/source-editor/components/source-editor.tsx @@ -1,7 +1,15 @@ -import { lazy, memo, Suspense } from 'react' +import { lazy, memo, Suspense, ElementType } from 'react' import { FullSizeLoadingSpinner } from '../../../shared/components/loading-spinner' import withErrorBoundary from '../../../infrastructure/error-boundary' import { ErrorBoundaryFallback } from '../../../shared/components/error-boundary-fallback' +import importOverleafModules from '../../../../macros/import-overleaf-module.macro' + +const writefullPromotion = importOverleafModules( + 'writefullEditorPromotion' +) as { + import: { default: ElementType } + path: string +}[] const CodeMirrorEditor = lazy( () => @@ -11,6 +19,9 @@ const CodeMirrorEditor = lazy( function SourceEditor() { return (