feat/enh: show user count in channels

This commit is contained in:
Timothy Jaeryang Baek 2025-11-25 03:46:30 -05:00
parent a7ee36266a
commit 3b5710d0cd
4 changed files with 65 additions and 5 deletions

View file

@ -59,6 +59,7 @@ class ChannelModel(BaseModel):
class ChannelResponse(ChannelModel):
write_access: bool = False
user_count: Optional[int] = None
class ChannelForm(BaseModel):

View file

@ -105,10 +105,13 @@ async def get_channel_by_id(id: str, user=Depends(get_verified_user)):
user.id, type="write", access_control=channel.access_control, strict=False
)
user_count = len(get_users_with_access("read", channel.access_control))
return ChannelResponse(
**{
**channel.model_dump(),
"write_access": write_access or user.role == "admin",
"user_count": user_count,
}
)

View file

@ -7,18 +7,22 @@
import { slide } from 'svelte/transition';
import { page } from '$app/stores';
import { WEBUI_API_BASE_URL } from '$lib/constants';
import UserMenu from '$lib/components/layout/Sidebar/UserMenu.svelte';
import PencilSquare from '../icons/PencilSquare.svelte';
import Tooltip from '../common/Tooltip.svelte';
import Sidebar from '../icons/Sidebar.svelte';
import { WEBUI_API_BASE_URL } from '$lib/constants';
import Hashtag from '../icons/Hashtag.svelte';
import Lock from '../icons/Lock.svelte';
import UserAlt from '../icons/UserAlt.svelte';
const i18n = getContext('i18n');
export let channel;
</script>
<nav class="sticky top-0 z-30 w-full px-1.5 py-1.5 -mb-8 flex items-center drag-region">
<nav class="sticky top-0 z-30 w-full px-1.5 py-1 -mb-8 flex items-center drag-region">
<div
id="navbar-bg-gradient-to-b"
class=" bg-linear-to-b via-50% from-white via-white to-transparent dark:from-gray-900 dark:via-gray-900 dark:to-transparent pointer-events-none absolute inset-0 -bottom-7 z-[-1]"
@ -57,13 +61,42 @@
"
>
{#if channel}
<div class="line-clamp-1 capitalize font-medium font-primary text-lg">
<div class="flex items-center gap-0.5 shrink-0">
<div class=" size-4 justify-center flex items-center">
{#if channel?.access_control === null}
<Hashtag className="size-3" strokeWidth="2.5" />
{:else}
<Lock className="size-5" strokeWidth="2" />
{/if}
</div>
<div
class=" text-left self-center overflow-hidden w-full line-clamp-1 capitalize flex-1"
>
{channel.name}
</div>
</div>
{/if}
</div>
<div class="self-start flex flex-none items-center text-gray-600 dark:text-gray-400">
<div class="self-start flex flex-none items-center text-gray-600 dark:text-gray-400 gap-1">
{#if channel?.user_count !== undefined}
<Tooltip content={$i18n.t('Users')}>
<button
class=" flex cursor-pointer py-1 px-1.5 border dark:border-gray-850 border-gray-50 rounded-xl text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-850 transition"
aria-label="User Count"
>
<div class=" flex items-center gap-0.5 m-auto self-center">
<UserAlt className=" size-4" strokeWidth="1.5" />
<div class="text-sm">
{channel.user_count}
</div>
</div>
</button>
</Tooltip>
{/if}
{#if $user !== undefined}
<UserMenu
className="max-w-[240px]"

View file

@ -0,0 +1,23 @@
<script lang="ts">
export let className = 'size-4';
export let strokeWidth = '1.5';
</script>
<svg
stroke-width={strokeWidth}
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
class={className}
>
<path
d="M5 20V19C5 15.134 8.13401 12 12 12V12C15.866 12 19 15.134 19 19V20"
stroke-linecap="round"
stroke-linejoin="round"
></path><path
d="M12 12C14.2091 12 16 10.2091 16 8C16 5.79086 14.2091 4 12 4C9.79086 4 8 5.79086 8 8C8 10.2091 9.79086 12 12 12Z"
stroke-linecap="round"
stroke-linejoin="round"
></path></svg
>