mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-11 20:05:19 +00:00
enh: dm active user indicator
This commit is contained in:
parent
d232e433e8
commit
4b6773885c
3 changed files with 35 additions and 4 deletions
|
|
@ -125,6 +125,12 @@ class UserIdNameResponse(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
class UserIdNameStatusResponse(BaseModel):
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
is_active: bool
|
||||||
|
|
||||||
|
|
||||||
class UserInfoListResponse(BaseModel):
|
class UserInfoListResponse(BaseModel):
|
||||||
users: list[UserInfoResponse]
|
users: list[UserInfoResponse]
|
||||||
total: int
|
total: int
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ from open_webui.socket.main import (
|
||||||
)
|
)
|
||||||
from open_webui.models.users import (
|
from open_webui.models.users import (
|
||||||
UserIdNameResponse,
|
UserIdNameResponse,
|
||||||
|
UserIdNameStatusResponse,
|
||||||
UserListResponse,
|
UserListResponse,
|
||||||
UserModelResponse,
|
UserModelResponse,
|
||||||
Users,
|
Users,
|
||||||
|
|
@ -68,7 +69,7 @@ router = APIRouter()
|
||||||
|
|
||||||
class ChannelListItemResponse(ChannelModel):
|
class ChannelListItemResponse(ChannelModel):
|
||||||
user_ids: Optional[list[str]] = None # 'dm' channels only
|
user_ids: Optional[list[str]] = None # 'dm' channels only
|
||||||
users: Optional[list[UserIdNameResponse]] = None # 'dm' channels only
|
users: Optional[list[UserIdNameStatusResponse]] = None # 'dm' channels only
|
||||||
|
|
||||||
last_message_at: Optional[int] = None # timestamp in epoch (time_ns)
|
last_message_at: Optional[int] = None # timestamp in epoch (time_ns)
|
||||||
unread_count: int = 0
|
unread_count: int = 0
|
||||||
|
|
@ -97,7 +98,12 @@ async def get_channels(user=Depends(get_verified_user)):
|
||||||
for member in Channels.get_members_by_channel_id(channel.id)
|
for member in Channels.get_members_by_channel_id(channel.id)
|
||||||
]
|
]
|
||||||
users = [
|
users = [
|
||||||
UserIdNameResponse(**user.model_dump())
|
UserIdNameStatusResponse(
|
||||||
|
**{
|
||||||
|
**user.model_dump(),
|
||||||
|
"is_active": get_active_status_by_user_id(user.id),
|
||||||
|
}
|
||||||
|
)
|
||||||
for user in Users.get_users_by_user_ids(user_ids)
|
for user in Users.get_users_by_user_ids(user_ids)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { channels, mobile, showSidebar, user } from '$lib/stores';
|
import { channels, mobile, showSidebar, user } from '$lib/stores';
|
||||||
|
import { getUserActiveStatusById } from '$lib/apis/users';
|
||||||
import { updateChannelById, updateChannelMemberActiveStatusById } from '$lib/apis/channels';
|
import { updateChannelById, updateChannelMemberActiveStatusById } from '$lib/apis/channels';
|
||||||
import { WEBUI_API_BASE_URL } from '$lib/constants';
|
import { WEBUI_API_BASE_URL } from '$lib/constants';
|
||||||
|
|
||||||
|
|
@ -83,8 +84,9 @@
|
||||||
<div>
|
<div>
|
||||||
{#if channel?.type === 'dm'}
|
{#if channel?.type === 'dm'}
|
||||||
{#if channel?.users}
|
{#if channel?.users}
|
||||||
<div class="flex ml-[1px] mr-0.5">
|
{@const channelMembers = channel.users.filter((u) => u.id !== $user?.id)}
|
||||||
{#each channel.users.filter((u) => u.id !== $user?.id).slice(0, 2) as u, index}
|
<div class="flex ml-[1px] mr-0.5 relative">
|
||||||
|
{#each channelMembers.slice(0, 2) as u, index}
|
||||||
<img
|
<img
|
||||||
src={`${WEBUI_API_BASE_URL}/users/${u.id}/profile/image`}
|
src={`${WEBUI_API_BASE_URL}/users/${u.id}/profile/image`}
|
||||||
alt={u.name}
|
alt={u.name}
|
||||||
|
|
@ -94,6 +96,23 @@
|
||||||
: ''}"
|
: ''}"
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
|
{#if channelMembers.length === 1}
|
||||||
|
<div class="absolute bottom-0 right-0">
|
||||||
|
<span class="relative flex size-2">
|
||||||
|
{#if channelMembers[0]?.is_active}
|
||||||
|
<span
|
||||||
|
class="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75"
|
||||||
|
></span>
|
||||||
|
{/if}
|
||||||
|
<span
|
||||||
|
class="relative inline-flex size-2 rounded-full {channelMembers[0]?.is_active
|
||||||
|
? 'bg-green-500'
|
||||||
|
: 'bg-gray-300 dark:bg-gray-700'} border-[1.5px] border-white dark:border-gray-900"
|
||||||
|
></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<Users className="size-4 ml-1 mr-0.5" strokeWidth="2" />
|
<Users className="size-4 ml-1 mr-0.5" strokeWidth="2" />
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue