Merge pull request #18891 from overleaf/rh-share-modal-when-over-limit

[web]: Show share modal when over collaborator limit

GitOrigin-RevId: 6f5594310f21e481d5837ff8d7f098668ecd2957
This commit is contained in:
roo hutton 2024-06-28 07:18:21 +01:00 committed by Copybot
parent 67dbf743e1
commit 853c1153e1
2 changed files with 42 additions and 2 deletions

View file

@ -14,10 +14,10 @@ function EditorNavigationToolbar() {
const { onlineUsersArray } = useOnlineUsersContext() const { onlineUsersArray } = useOnlineUsersContext()
const { openDoc } = useEditorManagerContext() const { openDoc } = useEditorManagerContext()
const handleOpenShareModal = () => { const handleOpenShareModal = useCallback(() => {
eventTracking.sendMBOnce('ide-open-share-modal-once') eventTracking.sendMBOnce('ide-open-share-modal-once')
setShowShareModal(true) setShowShareModal(true)
} }, [])
const handleHideShareModal = useCallback(() => { const handleHideShareModal = useCallback(() => {
setShowShareModal(false) setShowShareModal(false)
@ -37,6 +37,7 @@ function EditorNavigationToolbar() {
<EditorOverLimitModal /> <EditorOverLimitModal />
<NewShareProjectModal <NewShareProjectModal
show={showShareModal} show={showShareModal}
handleOpen={handleOpenShareModal}
handleHide={handleHideShareModal} handleHide={handleHideShareModal}
/> />
</> </>

View file

@ -10,6 +10,8 @@ import { useProjectContext } from '@/shared/context/project-context'
import { useSplitTestContext } from '@/shared/context/split-test-context' import { useSplitTestContext } from '@/shared/context/split-test-context'
import { sendMB } from '@/infrastructure/event-tracking' import { sendMB } from '@/infrastructure/event-tracking'
import { ProjectContextUpdateValue } from '@/shared/context/types/project-context' import { ProjectContextUpdateValue } from '@/shared/context/types/project-context'
import { useEditorContext } from '@/shared/context/editor-context'
import customLocalStorage from '@/infrastructure/local-storage'
type ShareProjectContextValue = { type ShareProjectContextValue = {
updateProject: (project: ProjectContextUpdateValue) => void updateProject: (project: ProjectContextUpdateValue) => void
@ -24,6 +26,8 @@ type ShareProjectContextValue = {
> >
} }
const SHOW_MODAL_COOLDOWN_PERIOD = 24 * 60 * 60 * 1000 // 24 hours
const ShareProjectContext = createContext<ShareProjectContextValue | undefined>( const ShareProjectContext = createContext<ShareProjectContextValue | undefined>(
undefined undefined
) )
@ -43,12 +47,14 @@ export function useShareProjectContext() {
type ShareProjectModalProps = { type ShareProjectModalProps = {
handleHide: () => void handleHide: () => void
show: boolean show: boolean
handleOpen: () => void
animation?: boolean animation?: boolean
} }
const ShareProjectModal = React.memo(function ShareProjectModal({ const ShareProjectModal = React.memo(function ShareProjectModal({
handleHide, handleHide,
show, show,
handleOpen,
animation = true, animation = true,
}: ShareProjectModalProps) { }: ShareProjectModalProps) {
const [inFlight, setInFlight] = const [inFlight, setInFlight] =
@ -56,9 +62,42 @@ const ShareProjectModal = React.memo(function ShareProjectModal({
const [error, setError] = useState<ShareProjectContextValue['error']>() const [error, setError] = useState<ShareProjectContextValue['error']>()
const project = useProjectContext() const project = useProjectContext()
const { isProjectOwner } = useEditorContext()
const { splitTestVariants } = useSplitTestContext() const { splitTestVariants } = useSplitTestContext()
// split test: link-sharing-warning
// show the new share modal if project owner
// is over collaborator limit (once every 24 hours)
useEffect(() => {
const hasExceededCollaboratorLimit = () => {
if (!isProjectOwner || !project.features) {
return false
}
if (project.features.collaborators === -1) {
return false
}
return (
project.members.filter(member => member.privileges === 'readAndWrite')
.length > (project.features.collaborators ?? 1)
)
}
if (hasExceededCollaboratorLimit()) {
const localStorageKey = `last-shown-share-modal.${project._id}`
const lastShownShareModalTime =
customLocalStorage.getItem(localStorageKey)
if (
!lastShownShareModalTime ||
lastShownShareModalTime + SHOW_MODAL_COOLDOWN_PERIOD < Date.now()
) {
handleOpen()
customLocalStorage.setItem(localStorageKey, Date.now())
}
}
}, [project, isProjectOwner, handleOpen])
// send tracking event when the modal is opened // send tracking event when the modal is opened
useEffect(() => { useEffect(() => {
if (show) { if (show) {