Merge pull request #15046 from overleaf/jdt-gramr-ad

creating notification for grammarly collab ad

GitOrigin-RevId: 984869bb561a2b2d3210f1018b93b24aedef9783
This commit is contained in:
Jimmy Domagala-Tang 2023-12-04 10:10:05 -05:00 committed by Copybot
parent a439f8b490
commit e57806b204
5 changed files with 93 additions and 0 deletions

View file

@ -66,6 +66,8 @@ block content
.system-message-content
| {{htmlContent}}
grammarly-advert()
if hasFeature('saas')
legacy-editor-warning(delay=10000)

View file

@ -0,0 +1,72 @@
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'
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)
}, [])
useEffect(() => {
const hasDismissedGrammarlyAdvert = customLocalStorage.getItem(
'editor.has_dismissed_grammarly_advert'
)
// promotion ends on december 16th, 2023 at 00:00 UTC
const promotionEnded =
new Date() > new Date(Date.UTC(2023, 11, 16, 0, 0, 0))
const showGrammarlyAdvert =
grammarlyInstalled && !hasDismissedGrammarlyAdvert && !promotionEnded
if (showGrammarlyAdvert) {
eventTracking.sendMB('grammarly-advert-shown')
setShow(true)
}
}, [grammarlyInstalled, setShow])
const handleClose = useCallback(() => {
setShow(false)
customLocalStorage.setItem('editor.has_dismissed_grammarly_advert', true)
eventTracking.sendMB('grammarly-advert-dismissed')
}, [])
if (!show) {
return null
}
return (
<div className="alert alert-info grammarly-advert" role="alert">
<div className="grammarly-advert-container">
<div className="advert-content">
<p>
Overleafers get a limited-time 30% discount on Grammarly Premium.
(Hurry! Offer ends December 16.)
</p>
<a
className="advert-link"
onClick={() => eventTracking.sendMB('grammarly-advert-clicked')}
href="https://www.grammarly.com/upgrade?transaction_id=10264119b53f745bed2cdca3c3e4a5&affiliateNetwork=ho&utm_campaign=Overleaf&affiliateID=142242&utm_source=program"
target="_blank"
rel="noopener"
>
Claim my discount
</a>
</div>
<div className="grammarly-notification-close-btn">
<button aria-label="Close" onClick={handleClose}>
<MaterialIcon type="close" />
</button>
</div>
</div>
</div>
)
}

View file

@ -0,0 +1,9 @@
import App from '../../../base'
import { react2angular } from 'react2angular'
import { rootContext } from '../../../shared/context/root-context'
import GrammarlyAdvert from '../components/grammarly-advert'
App.component(
'grammarlyAdvert',
react2angular(rootContext.use(GrammarlyAdvert))
)

View file

@ -56,6 +56,7 @@ import './shared/context/controllers/root-context-controller'
import './features/editor-navigation-toolbar/controllers/editor-navigation-toolbar-controller'
import './features/pdf-preview/controllers/pdf-preview-controller'
import './features/share-project-modal/controllers/react-share-project-modal-controller'
import './features/source-editor/controllers/grammarly-advert-controller'
import './features/history/controllers/history-controller'
import './features/editor-left-menu/controllers/editor-left-menu-controller'
import { cleanupServiceWorker } from './utils/service-worker-cleanup'

View file

@ -711,6 +711,7 @@ CodeMirror
}
}
.grammarly-advert,
.legacy-editor-warning {
width: 500px;
@ -740,6 +741,14 @@ CodeMirror
}
}
.grammarly-advert-container {
display: flex;
.grammarly-notification-close-btn > button {
background-color: @ol-blue;
}
}
grammarly-extension[data-grammarly-shadow-root='true'] {
z-index: 1;
}