mirror of
https://github.com/langgenius/dify.git
synced 2026-04-28 03:36:36 +08:00
show online users on the canvas
This commit is contained in:
parent
4019c12d26
commit
20320f3a27
@ -17,6 +17,7 @@ import RunAndHistory from './run-and-history'
|
|||||||
import EditingTitle from './editing-title'
|
import EditingTitle from './editing-title'
|
||||||
import EnvButton from './env-button'
|
import EnvButton from './env-button'
|
||||||
import VersionHistoryButton from './version-history-button'
|
import VersionHistoryButton from './version-history-button'
|
||||||
|
import OnlineUsers from './online-users'
|
||||||
|
|
||||||
export type HeaderInNormalProps = {
|
export type HeaderInNormalProps = {
|
||||||
components?: {
|
components?: {
|
||||||
@ -60,6 +61,8 @@ const HeaderInNormal = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className='flex items-center gap-2'>
|
<div className='flex items-center gap-2'>
|
||||||
{components?.left}
|
{components?.left}
|
||||||
|
<OnlineUsers />
|
||||||
|
<Divider type='vertical' className='mx-auto h-3.5' />
|
||||||
<EnvButton disabled={nodesReadOnly} />
|
<EnvButton disabled={nodesReadOnly} />
|
||||||
<Divider type='vertical' className='mx-auto h-3.5' />
|
<Divider type='vertical' className='mx-auto h-3.5' />
|
||||||
<RunAndHistory />
|
<RunAndHistory />
|
||||||
|
|||||||
50
web/app/components/workflow/header/online-users.tsx
Normal file
50
web/app/components/workflow/header/online-users.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
'use client'
|
||||||
|
import Avatar from '@/app/components/base/avatar'
|
||||||
|
import { useCollaboration } from '../collaboration/hooks/use-collaboration'
|
||||||
|
import { useStore } from '../store'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
|
const OnlineUsers = () => {
|
||||||
|
const appId = useStore(s => s.appId)
|
||||||
|
const { onlineUsers } = useCollaboration(appId)
|
||||||
|
|
||||||
|
if (!onlineUsers || onlineUsers.length === 0)
|
||||||
|
return null
|
||||||
|
|
||||||
|
// Show max 2 avatars directly, rest as count
|
||||||
|
const visibleUsers = onlineUsers.slice(0, 2)
|
||||||
|
const remainingCount = onlineUsers.length - 2
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center -space-x-2">
|
||||||
|
{visibleUsers.map((user, index) => (
|
||||||
|
<div
|
||||||
|
key={`${user.sid}-${index}`}
|
||||||
|
className="relative"
|
||||||
|
style={{ zIndex: visibleUsers.length - index }}
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
name={user.username || 'User'}
|
||||||
|
avatar={user.avatar}
|
||||||
|
size={28}
|
||||||
|
className="ring-2 ring-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{remainingCount > 0 && (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex items-center justify-center',
|
||||||
|
'h-7 w-7 rounded-full bg-gray-300',
|
||||||
|
'text-xs font-medium text-gray-700',
|
||||||
|
'ring-2 ring-white',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
+{remainingCount}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OnlineUsers
|
||||||
Loading…
Reference in New Issue
Block a user