This commit is contained in:
Timothy Jaeryang Baek 2025-11-30 10:40:24 -05:00
parent 3f1d9ccbf8
commit 39645102d1
3 changed files with 35 additions and 7 deletions

View file

@ -107,6 +107,12 @@ class UserModel(BaseModel):
model_config = ConfigDict(from_attributes=True)
class UserStatusModel(UserModel):
is_active: bool = False
model_config = ConfigDict(from_attributes=True)
class ApiKey(Base):
__tablename__ = "api_key"
@ -179,7 +185,7 @@ class UserIdNameResponse(BaseModel):
class UserIdNameStatusResponse(BaseModel):
id: str
name: str
is_active: bool = False
is_active: Optional[bool] = None
class UserInfoListResponse(BaseModel):
@ -431,7 +437,7 @@ class UsersTable:
"total": total,
}
def get_users_by_user_ids(self, user_ids: list[str]) -> list[UserModel]:
def get_users_by_user_ids(self, user_ids: list[str]) -> list[UserStatusModel]:
with get_db() as db:
users = db.query(User).filter(User.id.in_(user_ids)).all()
return [UserModel.model_validate(user) for user in users]

View file

@ -219,8 +219,8 @@ async def create_new_channel(
class ChannelFullResponse(ChannelResponse):
user_ids: Optional[list[str]] = None # 'dm' channels only
users: Optional[list[UserIdNameResponse]] = None # 'dm' channels only
user_ids: Optional[list[str]] = None # 'group'/'dm' channels only
users: Optional[list[UserIdNameStatusResponse]] = None # 'group'/'dm' channels only
last_read_at: Optional[int] = None # timestamp in epoch (time_ns)
unread_count: int = 0
@ -246,8 +246,11 @@ async def get_channel_by_id(id: str, user=Depends(get_verified_user)):
user_ids = [
member.user_id for member in Channels.get_members_by_channel_id(channel.id)
]
users = [
UserIdNameResponse(**user.model_dump())
UserIdNameStatusResponse(
**{**user.model_dump(), "is_active": Users.is_user_active(user.id)}
)
for user in Users.get_users_by_user_ids(user_ids)
]

View file

@ -76,8 +76,9 @@
<div class="flex items-center gap-0.5 shrink-0">
{#if channel?.type === 'dm'}
{#if channel?.users}
<div class="flex mr-1.5">
{#each channel.users.filter((u) => u.id !== $user?.id).slice(0, 2) as u, index}
{@const channelMembers = channel.users.filter((u) => u.id !== $user?.id)}
<div class="flex mr-1.5 relative">
{#each channelMembers.slice(0, 2) as u, index}
<img
src={`${WEBUI_API_BASE_URL}/users/${u.id}/profile/image`}
alt={u.name}
@ -87,6 +88,24 @@
: ''}"
/>
{/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>
{:else}
<Users className="size-4 ml-1 mr-0.5" strokeWidth="2" />