Files
Verso/services/web/frontend/js/features/editor-navigation-toolbar/components/online-users-widget.tsx
T
Rebeka DekanyandCopybot d751b88e6b Bootstrap files and folders cleanup (#27692)
* Remove icons folder

* Create folders for badge, button, and dropdown components

* Remove Bootstrap 5 from test

* Rename `getBootstrap5Breakpoint` to `getBootstrapBreakpoint`

* Cleanup and update BS 5 comments

* Move components to the shared folder

* Rename `tooltips-bs5` to `tooltip`

* Remove `-bs5` suffix

* Fix path

* Delete BS3 version file

* Rename `_form_marketing-bootstrap-5` to `_form_marketing`

* Delete BS3 version file

* Rename `_contact_general_modal-marketing-bootstrap-5` to `_contact_general_modal-marketing`

* Delete BS3 version file

* Rename `_contact_modal-marketing-bootstrap-5` to `_contact_modal-marketing`

* Delete BS3 version file

* Rename `thin-footer-bootstrap-5` to `thin-footer`

* Delete BS3 version file

* Rename `language-picker-bootstrap-5` to `language-picker`

* Rename `fat-footer-react-bootstrap-5` to `fat-footer-react`

* Delete BS3 version file

* Rename `navbar-marketing-bootstrap-5` to `navbar-marketing`

* Rename `navbar-marketing-react-bootstrap-5` to `navbar-marketing-react`

* Delete BS3 version file

* Rename `layout-website-redesign-cms-bootstrap-5` to `layout-website-redesign-cms`

* Source format

* Fix path

GitOrigin-RevId: cf0f5db7c84cf545c69213dcc271d9ff17fe5db7
2025-08-11 08:06:16 +00:00

131 lines
3.5 KiB
TypeScript

import React from 'react'
import { useTranslation } from 'react-i18next'
import {
Dropdown,
DropdownHeader,
DropdownItem,
DropdownMenu,
DropdownToggle,
} from '@/shared/components/dropdown/dropdown-menu'
import { getBackgroundColorForUserId } from '@/shared/utils/colors'
import OLTooltip from '@/shared/components/ol/ol-tooltip'
import MaterialIcon from '@/shared/components/material-icon'
import { OnlineUser } from '@/features/ide-react/context/online-users-context'
function OnlineUsersWidget({
onlineUsers,
goToUser,
}: {
onlineUsers: OnlineUser[]
goToUser: (user: OnlineUser) => void
}) {
const { t } = useTranslation()
const shouldDisplayDropdown = onlineUsers.length >= 4
if (shouldDisplayDropdown) {
return (
<Dropdown className="online-users" align="end">
<DropdownToggle
id="online-users"
as={DropDownToggleButton}
// @ts-ignore: fix type of DropdownToggle with "as" prop so that it can accept
// custom props for that component
onlineUserCount={onlineUsers.length}
/>
<DropdownMenu>
<DropdownHeader aria-hidden="true">
{t('connected_users')}
</DropdownHeader>
{onlineUsers.map((user, index) => (
<li role="none" key={`${user.user_id}_${index}`}>
<DropdownItem
as="button"
tabIndex={-1}
onClick={() => goToUser(user)}
>
<UserIcon user={user} showName />
</DropdownItem>
</li>
))}
</DropdownMenu>
</Dropdown>
)
} else {
return (
<div className="online-users">
{onlineUsers.map((user, index) => (
<OLTooltip
key={`${user.user_id}_${index}`}
id="online-user"
description={user.name}
overlayProps={{ placement: 'bottom', trigger: ['hover', 'focus'] }}
tooltipProps={{ translate: 'no' }}
>
<span>
{/* OverlayTrigger won't fire unless UserIcon is wrapped in a span */}
<UserIcon user={user} onClick={goToUser} />
</span>
</OLTooltip>
))}
</div>
)
}
}
function UserIcon({
user,
showName,
onClick,
}: {
user: OnlineUser
showName?: boolean
onClick?: (user: OnlineUser) => void
}) {
const backgroundColor = getBackgroundColorForUserId(user.user_id)
function handleOnClick() {
onClick?.(user)
}
const [character] = [...user.name]
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<span onClick={handleOnClick}>
<span className="online-user" style={{ backgroundColor }}>
{character}
</span>
{showName && user.name}
</span>
)
}
const DropDownToggleButton = React.forwardRef<
HTMLButtonElement,
{ onlineUserCount: number; onClick: React.MouseEventHandler }
>((props, ref) => {
const { t } = useTranslation()
return (
<OLTooltip
id="connected-users"
description={t('connected_users')}
overlayProps={{ placement: 'left' }}
>
<button
type="button"
className="online-user online-user-multi"
onClick={props.onClick} // required by Bootstrap Dropdown to trigger an opening
ref={ref}
>
<strong>{props.onlineUserCount}</strong>&nbsp;
<MaterialIcon type="groups" />
</button>
</OLTooltip>
)
})
DropDownToggleButton.displayName = 'DropDownToggleButton'
export default OnlineUsersWidget