Skip to content

Commit

Permalink
fix: improve presence menu performance
Browse files Browse the repository at this point in the history
  • Loading branch information
stipsan committed Dec 13, 2024
1 parent 9d075f4 commit 9a02a4c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ export function PresenceMenu() {
focused={focusedId === item.user.id}
key={item.user.id}
onFocus={handleItemFocus}
presence={item}
locations={item.locations}
user={item.user}
/>
))}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as PathUtils from '@sanity/util/paths'
import {orderBy} from 'lodash'
import {type ForwardedRef, forwardRef, memo, useCallback, useEffect, useMemo, useState} from 'react'
import {memo, useCallback, useEffect, useState} from 'react'
import {IntentLink} from 'sanity/router'

import {MenuItem} from '../../../../../ui-components'
Expand All @@ -11,19 +11,15 @@ import {type GlobalPresence} from '../../../../store'
interface PresenceListRowProps {
focused: boolean
onFocus: (id: string) => void
presence: GlobalPresence
locations: GlobalPresence['locations']
user: GlobalPresence['user']
}

export const PresenceMenuItem = memo(function PresenceMenuItem(props: PresenceListRowProps) {
const {presence, focused, onFocus} = props
const {locations, user, focused, onFocus} = props
const [menuItemElement, setMenuItemElement] = useState<HTMLElement | null>(null)
const {t} = useTranslation()

const lastActiveLocation = orderBy(presence.locations || [], ['lastActiveAt'], ['desc']).find(
(location) => location.documentId,
)
const hasLink = Boolean(lastActiveLocation?.documentId)

/**
* This is a workaround to keep focus on the selected menu item
* when the list of users in the menu is updated
Expand All @@ -40,42 +36,47 @@ export const PresenceMenuItem = memo(function PresenceMenuItem(props: PresenceLi
}, [menuItemElement, focused])

const handleFocus = useCallback(() => {
onFocus(presence.user.id)
}, [onFocus, presence.user.id])
onFocus(user.id)
}, [onFocus, user.id])

const LinkComponent = useMemo(
() =>
// eslint-disable-next-line @typescript-eslint/no-shadow
forwardRef(function LinkComponent(linkProps, ref: ForwardedRef<HTMLAnchorElement>) {
if (!lastActiveLocation?.path) return null

return (
<IntentLink
{...linkProps}
intent="edit"
params={{
id: lastActiveLocation?.documentId,
path: PathUtils.toString(lastActiveLocation?.path),
}}
ref={ref}
/>
)
}),
[lastActiveLocation],
const lastActiveLocation = orderBy(locations || [], ['lastActiveAt'], ['desc']).find(
(location) => location.documentId,
)
const hasLink = Boolean(lastActiveLocation?.documentId)

if (lastActiveLocation) {
return (
<MenuItem
as={IntentLink}
// @ts-expect-error - `intent` is valid when using `IntentLink`
intent="edit"
params={{
id: lastActiveLocation.documentId,
path: PathUtils.toString(lastActiveLocation.path),
}}
// Shared props
data-as="a"
onFocus={handleFocus}
preview={<UserAvatar size={1} user={user} />}
ref={setMenuItemElement}
text={user.displayName}
/>
)
}

return (
<MenuItem
as={lastActiveLocation ? LinkComponent : 'div'}
data-as="a"
as="div"
disabled={!hasLink}
onFocus={handleFocus}
preview={<UserAvatar key={presence.user.id} size={1} user={presence.user} />}
ref={setMenuItemElement}
text={presence.user.displayName}
tooltipProps={
hasLink ? undefined : {content: t('presence.not-in-a-document'), placement: 'left'}
}
// Shared props
data-as="a"
onFocus={handleFocus}
preview={<UserAvatar size={1} user={user} />}
ref={setMenuItemElement}
text={user.displayName}
/>
)
})

0 comments on commit 9a02a4c

Please sign in to comment.