mirror of https://github.com/langgenius/dify.git
add online users avatar
This commit is contained in:
parent
20320f3a27
commit
2e11b1298e
|
|
@ -8,6 +8,7 @@ export type AvatarProps = {
|
|||
size?: number
|
||||
className?: string
|
||||
textClassName?: string
|
||||
backgroundColor?: string
|
||||
}
|
||||
const Avatar = ({
|
||||
name,
|
||||
|
|
@ -15,9 +16,18 @@ const Avatar = ({
|
|||
size = 30,
|
||||
className,
|
||||
textClassName,
|
||||
backgroundColor,
|
||||
}: AvatarProps) => {
|
||||
const avatarClassName = 'shrink-0 flex items-center rounded-full bg-primary-600'
|
||||
const style = { width: `${size}px`, height: `${size}px`, fontSize: `${size}px`, lineHeight: `${size}px` }
|
||||
const avatarClassName = backgroundColor
|
||||
? 'shrink-0 flex items-center rounded-full'
|
||||
: 'shrink-0 flex items-center rounded-full bg-primary-600'
|
||||
const style = {
|
||||
width: `${size}px`,
|
||||
height: `${size}px`,
|
||||
fontSize: `${size}px`,
|
||||
lineHeight: `${size}px`,
|
||||
...(backgroundColor && !avatar ? { backgroundColor } : {}),
|
||||
}
|
||||
const [imgError, setImgError] = useState(false)
|
||||
|
||||
const handleError = () => {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,16 @@ import Avatar from '@/app/components/base/avatar'
|
|||
import { useCollaboration } from '../collaboration/hooks/use-collaboration'
|
||||
import { useStore } from '../store'
|
||||
import cn from '@/utils/classnames'
|
||||
import { ChevronDown } from '@/app/components/base/icons/src/vender/solid/arrows'
|
||||
|
||||
const getUserColor = (id: string) => {
|
||||
const colors = ['#3B82F6', '#EF4444', '#10B981', '#F59E0B', '#8B5CF6', '#EC4899', '#06B6D4', '#84CC16']
|
||||
const hash = id.split('').reduce((a, b) => {
|
||||
a = ((a << 5) - a) + b.charCodeAt(0)
|
||||
return a & a
|
||||
}, 0)
|
||||
return colors[Math.abs(hash) % colors.length]
|
||||
}
|
||||
|
||||
const OnlineUsers = () => {
|
||||
const appId = useStore(s => s.appId)
|
||||
|
|
@ -11,38 +21,53 @@ const OnlineUsers = () => {
|
|||
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
|
||||
// Display logic:
|
||||
// 1-3 users: show all avatars
|
||||
// 4+ users: show 2 avatars + count + arrow
|
||||
const shouldShowCount = onlineUsers.length >= 4
|
||||
const maxVisible = shouldShowCount ? 2 : 3
|
||||
const visibleUsers = onlineUsers.slice(0, maxVisible)
|
||||
const remainingCount = onlineUsers.length - maxVisible
|
||||
|
||||
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',
|
||||
<div className="flex items-center rounded-full bg-white px-1 py-1">
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center -space-x-2">
|
||||
{visibleUsers.map((user, index) => {
|
||||
const userColor = getUserColor(user.user_id)
|
||||
return (
|
||||
<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"
|
||||
backgroundColor={userColor}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
{remainingCount > 0 && (
|
||||
<div
|
||||
className={cn(
|
||||
'flex h-7 w-7 items-center justify-center',
|
||||
'rounded-full bg-gray-300',
|
||||
'text-xs font-medium text-gray-700',
|
||||
'ring-2 ring-white',
|
||||
)}
|
||||
>
|
||||
+{remainingCount}
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
+{remainingCount}
|
||||
</div>
|
||||
)}
|
||||
{remainingCount > 0 && (
|
||||
<ChevronDown className="ml-1 h-3 w-3 text-gray-500" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue