This commit is contained in:
Timothy Jaeryang Baek 2026-10-07 16:06:08 +04:00
parent f4011ebe45
commit 7937e8a1fd
6 changed files with 112 additions and 99 deletions

View file

@ -404,7 +404,7 @@
</div>
</div>
<div class=" pb-[1rem] px-2.5">
<div class=" pb-3 px-3">
<MessageInput
id="root"
bind:chatInputElement
@ -460,7 +460,7 @@
maxWidth={640}
className="h-full"
>
<div class="h-full w-full shadow-xl">
<div class="h-full w-full border-l border-gray-100/60 dark:border-gray-800/40">
<Thread
{threadId}
{channel}

View file

@ -894,13 +894,15 @@
{/if}
<div
id="message-input-container"
class="flex-1 flex flex-col relative w-full shadow-lg rounded-3xl border border-gray-50 dark:border-gray-850/30 hover:border-gray-100 focus-within:border-gray-100 hover:dark:border-gray-800 focus-within:dark:border-gray-800 transition px-0.5 bg-white/90 dark:bg-gray-400/5 dark:text-gray-100"
class="flex-1 flex flex-col relative w-full shadow-sm rounded-2xl border border-gray-100/60 dark:border-gray-800/50 hover:border-gray-100 focus-within:border-gray-100 hover:dark:border-gray-800 focus-within:dark:border-gray-800 transition bg-white dark:bg-gray-400/5 dark:text-gray-100"
dir={$settings?.chatDirection ?? 'auto'}
>
{#if replyToMessage !== null}
<div class="px-3 pt-3 text-left w-full flex flex-col z-10">
<div class="px-3 pt-2 text-left w-full flex flex-col z-10">
<div class="flex items-center justify-between w-full">
<div class="pl-[0.0625rem] flex items-center gap-2 text-sm">
<div
class="min-w-0 flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400"
>
<div class="translate-y-[0.5px]">
<span class=""
>{$i18n.t('Replying to {{NAME}}', {
@ -911,12 +913,14 @@
</div>
<div>
<button
class="flex items-center dark:text-gray-500"
class="flex size-6 shrink-0 items-center justify-center rounded-md text-gray-500 hover:bg-gray-50 dark:hover:bg-gray-800 dark:text-gray-400"
aria-label={$i18n.t('Cancel')}
type="button"
on:click={() => {
replyToMessage = null;
}}
>
<XMark />
<XMark className="size-3.5" />
</button>
</div>
</div>
@ -992,6 +996,7 @@
{#key $settings?.richTextInput && $settings?.showFormattingToolbar}
<RichTextInput
id="chat-input"
className="input-prose min-h-fit h-full text-sm!"
bind:this={chatInputElement}
json={true}
messageInput={true}
@ -1087,8 +1092,8 @@
</div>
</div>
<div class=" flex justify-between mt-0.5 mb-2 mx-0.5 max-w-full">
<div class="ml-1 self-end flex items-center flex-1 min-w-0">
<div class=" flex items-center justify-between gap-2 p-1.5 pt-0.5 max-w-full">
<div class="flex items-center flex-1 min-w-0">
<slot name="menu">
{#if acceptFiles}
<InputMenu
@ -1099,7 +1104,7 @@
>
<button
id="input-menu-button"
class="bg-transparent hover:bg-gray-100 text-gray-700 dark:text-white dark:hover:bg-gray-800 rounded-full size-[1.875rem] flex justify-center items-center outline-hidden focus:outline-hidden shrink-0"
class="bg-transparent hover:bg-gray-100 text-gray-500 dark:text-gray-400 dark:hover:bg-gray-800 rounded-lg size-7 flex justify-center items-center outline-hidden focus:outline-hidden shrink-0"
type="button"
aria-label={$i18n.t('More')}
>
@ -1107,7 +1112,7 @@
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-5"
class="size-4"
>
<path
d="M10.75 4.75a.75.75 0 0 0-1.5 0v4.5h-4.5a.75.75 0 0 0 0 1.5h4.5v4.5a.75.75 0 0 0 1.5 0v-4.5h4.5a.75.75 0 0 0 0-1.5h-4.5v-4.5Z"
@ -1119,12 +1124,12 @@
</slot>
</div>
<div class="self-end flex space-x-1 mr-1 shrink-0 gap-[0.03125rem]">
<div class="flex items-center gap-1 shrink-0">
{#if content === ''}
<Tooltip content={$i18n.t('Record voice')}>
<button
id="voice-input-button"
class=" text-gray-600 dark:text-gray-300 hover:text-gray-700 dark:hover:text-gray-200 transition rounded-full p-[0.3125rem] mr-0.5 self-center"
class=" text-gray-600 dark:text-gray-300 hover:text-gray-700 dark:hover:text-gray-200 transition rounded-lg size-7 flex items-center justify-center"
type="button"
on:click={async () => {
try {
@ -1158,7 +1163,7 @@
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-5 h-5 translate-y-[0.5px]"
class="size-4"
>
<path d="M7 4a3 3 0 016 0v6a3 3 0 11-6 0V4z" />
<path
@ -1175,7 +1180,7 @@
<Tooltip content={$i18n.t('Stop')}>
<button
aria-label={$i18n.t('Stop')}
class="bg-white hover:bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-[0.3125rem]"
class="bg-white hover:bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800 transition rounded-full size-7 flex items-center justify-center"
on:click={() => {
onStop();
}}
@ -1184,7 +1189,7 @@
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="size-5"
class="size-4"
>
<path
fill-rule="evenodd"
@ -1203,7 +1208,7 @@
aria-label={$i18n.t('Send message')}
class="{content !== '' || files.length !== 0
? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
: 'text-white bg-gray-200 dark:text-gray-900 dark:bg-gray-700 disabled'} transition rounded-full p-[0.3125rem] self-center"
: 'text-white bg-gray-200 dark:text-gray-900 dark:bg-gray-700 disabled'} transition rounded-full size-7 flex items-center justify-center self-center"
type="submit"
disabled={content === '' && files.length === 0}
>
@ -1211,7 +1216,7 @@
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="size-5"
class="size-4"
>
<path
fill-rule="evenodd"

View file

@ -73,16 +73,16 @@
</div>
</Loader>
{:else if !thread}
<div class="px-5 max-w-full mx-auto">
<div class="px-4 max-w-full mx-auto">
{#if channel}
<div class="flex flex-col gap-1.5 pb-5 pt-10">
<div class="flex flex-col gap-1.5 pb-4 pt-8">
{#if channel?.type === 'dm'}
<div class="flex ml-[0.0625rem] mr-0.5">
{#each channel.users.filter((u) => u.id !== $user?.id).slice(0, 2) as u, index}
<img
src={`${WEBUI_API_BASE_URL}/users/${u.id}/profile/image`}
alt={u.name}
class=" size-7.5 rounded-full border-2 border-white dark:border-gray-900 {index ===
class=" size-7 rounded-full object-cover border-2 border-white dark:border-gray-900 {index ===
1
? '-ml-2.5'
: ''}"
@ -91,7 +91,7 @@
</div>
{/if}
<div class="text-2xl font-normal capitalize">
<div class="text-lg font-medium leading-6">
{#if channel?.name}
{channel.name}
{:else}
@ -102,7 +102,7 @@
{/if}
</div>
<div class=" text-gray-500">
<div class="text-xs leading-5 text-gray-500 dark:text-gray-400">
{$i18n.t(
'This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.',
{
@ -119,7 +119,7 @@
{/if}
{#if messageList.length > 0}
<hr class=" border-gray-50 dark:border-gray-700/20 py-2.5 w-full" />
<hr class=" border-gray-100/60 dark:border-gray-800/40 mb-2 w-full" />
{/if}
</div>
{/if}
@ -256,6 +256,6 @@
/>
{/each}
<div class="pb-6" />
<div class="pb-4"></div>
</div>
{/if}

View file

@ -23,7 +23,6 @@
import StructuredOutputRenderer from '$lib/components/chat/Messages/StructuredOutputRenderer.svelte';
import { buildOutputDisplayItems } from '$lib/components/chat/Messages/structuredOutput';
import ProfileImage from '$lib/components/chat/Messages/ProfileImage.svelte';
import Name from '$lib/components/chat/Messages/Name.svelte';
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
import Pencil from '$lib/components/icons/Pencil.svelte';
@ -181,7 +180,7 @@
class="swipe-reply-icon"
class:swipe-reply-icon--active={swipeOffsetX >= SWIPE_THRESHOLD}
>
<ArrowUpLeftAlt className="size-5" />
<ArrowUpLeftAlt className="size-4" />
</div>
</div>
{/if}
@ -190,17 +189,17 @@
id="message-{renderedMessageId}"
class="flex flex-col justify-between w-full max-w-full mx-auto group hover:bg-gray-300/5 dark:hover:bg-gray-700/5 relative {className
? className
: `px-5 ${
: `px-4 ${
replyToMessage
? 'border-l-4 border-blue-500 bg-blue-100/10 dark:bg-blue-100/5 pl-4'
? 'border-l-4 border-blue-500 bg-blue-100/10 dark:bg-blue-100/5 pl-3'
: ''
} ${
(message?.reply_to_message?.meta?.model_id ?? message?.reply_to_message?.user_id) ===
$user?.id
? 'border-l-4 border-orange-500 bg-orange-100/10 dark:bg-orange-100/5 pl-4'
? 'border-l-4 border-orange-500 bg-orange-100/10 dark:bg-orange-100/5 pl-3'
: ''
} ${message?.is_pinned ? 'bg-yellow-100/20 dark:bg-yellow-100/5' : ''}`} {showUserProfile
? 'pt-1.5 pb-0.5'
? 'pt-2.5 pb-0.5'
: ''}"
style="transform: translateX({swipeOffsetX}px); {swipeOffsetX > 0
? ''
@ -235,12 +234,13 @@
{#if onReply}
<Tooltip content={$i18n.t('Reply')}>
<button
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-0.5"
aria-label={$i18n.t('Reply')}
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-1"
on:click={() => {
onReply(message);
}}
>
<ArrowUpLeftAlt className="size-5" />
<ArrowUpLeftAlt className="size-4" />
</button>
</Tooltip>
{/if}
@ -263,6 +263,7 @@
{#if !thread && onThread}
<Tooltip content={$i18n.t('Reply in Thread')}>
<button
aria-label={$i18n.t('Reply in Thread')}
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-1"
on:click={() => {
onThread(message.id);
@ -305,7 +306,7 @@
{#if message?.is_pinned}
<div class="flex {showUserProfile ? 'mb-0.5' : 'mt-0.5'}">
<div class="ml-8.5 flex items-center gap-1 px-1 rounded-full text-xs">
<div class="ml-8 flex items-center gap-1 text-[0.6875rem] leading-4">
<Pin className="size-3 text-yellow-500 dark:text-yellow-300" />
<span class="text-gray-500">{$i18n.t('Pinned')}</span>
</div>
@ -315,11 +316,11 @@
{#if message?.reply_to_message?.user}
<div class="relative text-xs mb-1">
<div
class="absolute h-3 w-7 left-[1.125rem] top-2 rounded-tl-lg border-t-[1.5px] border-l-[1.5px] border-gray-200 dark:border-gray-700 z-0"
class="absolute h-3 w-5 left-3 top-2 rounded-tl-lg border-t-[1.5px] border-l-[1.5px] border-gray-200 dark:border-gray-700 z-0"
></div>
<button
class="ml-12 flex items-center space-x-2 relative z-0"
class="ml-8 flex min-w-0 max-w-[calc(100%-2rem)] items-center gap-1.5 relative z-0"
on:click={() => {
const messageElement = document.getElementById(`message-${replyToMessageId}`);
if (messageElement) {
@ -355,13 +356,15 @@
/>
{/if}
<div class="shrink-0">
<div class="max-w-[35%] shrink-0 truncate">
{message?.reply_to_message.meta?.model_name ??
message?.reply_to_message.user?.name ??
$i18n.t('Unknown User')}
</div>
<div class="italic text-sm text-gray-500 dark:text-gray-400 line-clamp-1 w-full flex-1">
<div
class="text-xs text-gray-500 dark:text-gray-400 line-clamp-1 min-w-0 flex-1 [&_.markdown-prose]:text-xs!"
>
<Markdown
id={`${renderedMessageId}-reply-to`}
content={message?.reply_to_message?.content}
@ -377,13 +380,13 @@
id="message-{renderedMessageId}"
dir={$settings.chatDirection}
>
<div class={`shrink-0 mr-1 w-9`}>
<div class="w-6 shrink-0">
{#if showUserProfile}
{#if message?.meta?.model_id}
<img
src={`${WEBUI_API_BASE_URL}/models/model/profile/image?id=${message.meta.model_id}`}
alt={message.meta.model_name ?? message.meta.model_id}
class="size-8 translate-y-1 ml-0.5 object-cover rounded-full"
class="size-6 mt-0.5 object-cover rounded-full"
on:error={(e) => {
// LICENSE covers this Open WebUI fallback logo.
// Do not alter, remove, obscure, or replace it except as LICENSE permits:
@ -394,35 +397,33 @@
{:else if message.user?.role === 'webhook'}
<ProfileImage
src={`${WEBUI_API_BASE_URL}/channels/webhooks/${message.user?.id}/profile/image`}
className={'size-8 ml-0.5'}
className={'size-6 mt-0.5 rounded-full!'}
/>
{:else}
<ProfilePreview user={message.user}>
<ProfileImage
src={`${WEBUI_API_BASE_URL}/users/${message.user?.id}/profile/image`}
className={'size-8 ml-0.5'}
className={'size-6 mt-0.5 rounded-full!'}
/>
</ProfilePreview>
{/if}
{:else}
<!-- <div class="w-7 h-7 rounded-full bg-transparent" /> -->
{#if message.created_at}
<div
class="mt-1.5 flex shrink-0 items-center text-xs self-center hover-reveal text-gray-500 font-normal first-letter:capitalize"
>
<Tooltip content={dayjs(message.created_at / 1000000).format('LLLL')}>
{dayjs(message.created_at / 1000000).format('HH:mm')}
</Tooltip>
</div>
{/if}
{:else if message.created_at}
<div
class="-mx-1 mt-1 flex items-center justify-center text-[0.6875rem] leading-4 tabular-nums hover-reveal text-gray-500 dark:text-gray-400"
>
<Tooltip content={dayjs(message.created_at / 1000000).format('LLLL')}>
{dayjs(message.created_at / 1000000).format('HH:mm')}
</Tooltip>
</div>
{/if}
</div>
<div class="flex-auto w-0 pl-2">
{#if showUserProfile}
<Name>
<div class=" self-end text-base shrink-0 font-normal truncate">
<div class="flex min-w-0 items-baseline gap-1.5 leading-5">
<div
class=" min-w-0 truncate text-[0.8125rem] font-medium text-gray-900 dark:text-gray-100"
>
{#if message?.meta?.model_id}
{message?.meta?.model_name ?? message?.meta?.model_id}
{:else}
@ -432,7 +433,7 @@
{#if message.created_at}
<div
class=" self-center text-xs text-gray-400 font-normal first-letter:capitalize ml-0.5 translate-y-[1px]"
class=" shrink-0 text-[0.6875rem] leading-4 text-gray-500 dark:text-gray-400 font-normal first-letter:capitalize"
>
<Tooltip content={dayjs(message.created_at / 1000000).format('LLLL')}>
<span class="line-clamp-1">
@ -448,7 +449,7 @@
</Tooltip>
</div>
{/if}
</Name>
</div>
{/if}
{#if message?.data === true}
@ -531,7 +532,11 @@
</div>
</div>
{:else}
<div class="min-w-full {pending ? 'opacity-50' : ''}">
<div
class="min-w-full [&_.markdown-prose]:text-sm! [&_.markdown-prose]:leading-[1.375rem]! {pending
? 'opacity-50'
: ''}"
>
{#if hasStructuredOutput}
<StructuredOutputRenderer
id={renderedMessageId}
@ -558,7 +563,7 @@
{#if (message?.reactions ?? []).length > 0}
<div>
<div class="flex items-center flex-wrap gap-y-1.5 gap-1 mt-1 mb-2">
<div class="flex items-center flex-wrap gap-1 mt-1 mb-1">
{#each message.reactions as reaction}
<Tooltip
content={$i18n.t('{{NAMES}} reacted with {{REACTION}}', {
@ -596,7 +601,7 @@
>
<button
{disabled}
class="flex items-center gap-1.5 transition rounded-xl px-2 py-1 cursor-pointer {reaction.users
class="flex min-h-6 items-center gap-1.5 text-sm leading-4 transition rounded-lg px-1.5 py-0.5 cursor-pointer {reaction.users
.map((u) => u.id)
.includes($user?.id)
? ' bg-blue-300/10 outline outline-blue-500/50 outline-1'
@ -607,10 +612,12 @@
}
}}
>
<Emoji shortCode={reaction.name} />
<Emoji className="size-3.5" shortCode={reaction.name} />
{#if reaction.users.length > 0}
<div class="text-xs font-normal text-gray-500 dark:text-gray-400">
<div
class="text-[0.6875rem] font-normal text-gray-500 dark:text-gray-400"
>
{reaction.users?.length}
</div>
{/if}
@ -626,7 +633,7 @@
>
<Tooltip content={$i18n.t('Add Reaction')}>
<div
class="flex items-center gap-1.5 bg-gray-500/10 hover:outline hover:outline-gray-700/30 dark:hover:outline-gray-300/30 hover:outline-1 transition rounded-xl px-1 py-1 cursor-pointer text-gray-500 dark:text-gray-400"
class="flex items-center gap-1.5 bg-gray-500/10 hover:outline hover:outline-gray-700/30 dark:hover:outline-gray-300/30 hover:outline-1 transition rounded-lg p-1 cursor-pointer text-gray-500 dark:text-gray-400"
>
<FaceSmile />
</div>
@ -640,14 +647,14 @@
{#if !thread && message.reply_count > 0}
<div class="flex items-center gap-1.5 -mt-0.5 mb-1.5">
<button
class="flex items-center text-xs py-1 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition"
class="flex min-w-0 items-center text-[0.6875rem] py-1 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition"
on:click={() => {
onThread(message.id);
}}
>
<span class="font-normal mr-1">
<span class="shrink-0 font-medium mr-1">
{$i18n.t('{{COUNT}} Replies', { COUNT: message.reply_count })}</span
><span>
><span class="truncate">
{' - '}{$i18n.t('Last reply')}
{dayjs.unix(message.latest_reply_at / 1000000000).fromNow()}</span
>

View file

@ -52,19 +52,19 @@
<PinnedMessagesModal bind:show={showChannelPinnedMessagesModal} {channel} {onPin} />
<ChannelInfoModal bind:show={showChannelInfoModal} {channel} {onUpdate} />
<nav class="sticky top-0 z-30 w-full px-1.5 py-1 -mb-8 flex items-center drag-region flex flex-col">
<nav class="sticky top-0 z-30 w-full px-3 py-1 -mb-8 flex items-center drag-region flex-col">
<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]"
></div>
<div class=" flex max-w-full w-full mx-auto px-1 pt-0.5 bg-transparent">
<div class=" flex max-w-full w-full mx-auto pt-0.5 bg-transparent">
<div class="flex items-center w-full max-w-full">
{#if $mobile}
<div
class="{$showSidebar
? 'md:hidden'
: ''} mr-1.5 mt-0.5 self-start flex flex-none items-center text-gray-600 dark:text-gray-400"
: ''} mr-1.5 mt-0.5 self-center flex flex-none items-center text-gray-600 dark:text-gray-400"
>
<Tooltip
content={$showSidebar ? $i18n.t('Close Sidebar') : $i18n.t('Open Sidebar')}
@ -86,23 +86,23 @@
{/if}
<div
class="flex-1 overflow-hidden max-w-full py-0.5 flex items-center
class="min-w-0 flex-1 overflow-hidden max-w-full py-0.5 flex items-center
{$showSidebar ? 'ml-1' : ''}
"
>
{#if channel}
<div class="flex items-center gap-0.5 shrink-0">
<div class="flex min-w-0 items-center gap-1.5">
{#if channel?.type === 'dm'}
{#if channel?.users}
{@const channelMembers = channel.users.filter((u) => u.id !== $user?.id)}
<div class="flex mr-1.5 relative">
<div class="flex shrink-0 relative">
{#each channelMembers.slice(0, 2) as u, index}
<img
src={`${WEBUI_API_BASE_URL}/users/${u.id}/profile/image`}
alt={u.name}
class=" size-6.5 rounded-full border-2 border-white dark:border-gray-900 {index ===
class=" size-5.5 rounded-full object-cover border border-white dark:border-gray-900 {index ===
1
? '-ml-3'
? '-ml-2'
: ''}"
/>
{/each}
@ -110,11 +110,6 @@
{#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
@ -126,19 +121,21 @@
{/if}
</div>
{:else}
<Users className="size-4 ml-1 mr-0.5" strokeWidth="2" />
<Users className="size-4" strokeWidth="1.5" />
{/if}
{:else}
<div class=" size-4.5 justify-center flex items-center">
<div class=" size-4 shrink-0 justify-center flex items-center">
{#if isPublicChannel(channel)}
<Hashtag className="size-3.5" strokeWidth="2.5" />
<Hashtag className="size-4" strokeWidth="1.5" />
{:else}
<Lock className="size-5" strokeWidth="2" />
<Lock className="size-4" strokeWidth="1.5" />
{/if}
</div>
{/if}
<div class=" text-left self-center overflow-hidden w-full line-clamp-1 flex-1">
<div
class=" min-w-0 truncate text-left text-sm font-medium leading-5 text-gray-700 dark:text-gray-300"
>
{#if channel?.name}
{channel.name}
{:else}
@ -153,19 +150,19 @@
</div>
<div
class="self-start flex flex-none items-center text-gray-600 dark:text-gray-400 gap-1 shrink-0"
class="self-center flex flex-none items-center text-gray-600 dark:text-gray-400 gap-1 shrink-0"
>
{#if channel}
<Tooltip content={$i18n.t('Pinned Messages')}>
<button
class=" flex cursor-pointer py-1.5 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"
class=" flex size-7 items-center justify-center cursor-pointer rounded-lg text-gray-500 dark:text-gray-400 hover:bg-gray-50/60 dark:hover:bg-gray-800/60 transition-colors"
aria-label={$i18n.t('Pinned Messages')}
type="button"
on:click={() => {
showChannelPinnedMessagesModal = true;
}}
>
<div class=" flex items-center gap-0.5 m-auto self-center shrink-0">
<div class=" flex items-center gap-1 m-auto self-center shrink-0">
<Pin className=" size-4" strokeWidth="1.5" />
</div>
</button>
@ -174,17 +171,17 @@
{#if channel?.user_count !== undefined}
<Tooltip content={$i18n.t('Users')}>
<button
class=" flex cursor-pointer shrink-0 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"
class=" flex h-7 items-center cursor-pointer shrink-0 px-1.5 rounded-lg text-gray-500 dark:text-gray-400 hover:bg-gray-50/60 dark:hover:bg-gray-800/60 transition-colors"
aria-label={$i18n.t('User Count')}
type="button"
on:click={() => {
showChannelInfoModal = true;
}}
>
<div class=" flex items-center gap-0.5 m-auto self-center shrink-0">
<div class=" flex items-center gap-1 m-auto self-center shrink-0">
<UserAlt className=" size-4" strokeWidth="1.5" />
<div class="text-sm shrink-0">
<div class="text-xs tabular-nums shrink-0">
{channel.user_count}
</div>
</div>

View file

@ -192,18 +192,22 @@
</script>
{#if channel}
<div class="flex flex-col w-full h-full bg-gray-50 dark:bg-gray-850">
<div class="sticky top-0 flex items-center justify-between px-3.5 py-3">
<div class=" font-normal text-lg">{$i18n.t('Thread')}</div>
<div class="flex flex-col w-full h-full bg-white dark:bg-gray-900">
<div
class="sticky top-0 flex min-h-10 items-center justify-between border-b border-gray-100/60 px-4 py-1.5 dark:border-gray-800/40"
>
<div class=" font-medium text-sm">{$i18n.t('Thread')}</div>
<div>
<button
class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300 p-2"
type="button"
aria-label={$i18n.t('Close')}
class="flex size-7 items-center justify-center rounded-lg text-gray-500 hover:bg-gray-50/60 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-800/60 dark:hover:text-gray-300"
on:click={() => {
onClose();
}}
>
<XMark />
<XMark className="size-4" />
</button>
</div>
</div>
@ -212,7 +216,7 @@
class="flex-1 min-h-0 w-full overflow-y-auto will-change-transform"
bind:this={messagesContainerElement}
>
<div class="pt-7">
<div class="pt-3">
{#if messages !== null}
<Messages
id={threadId}
@ -252,7 +256,7 @@
</div>
</div>
<div class=" pb-[1rem] px-2.5 w-full">
<div class=" pb-3 px-3 w-full">
<MessageInput
bind:replyToMessage
bind:chatInputElement
@ -262,7 +266,7 @@
placeholder={!channel?.write_access
? $i18n.t('You do not have permission to send messages in this thread.')
: $i18n.t('Reply to thread...')}
typingUsersClassName="from-gray-50 dark:from-gray-850"
typingUsersClassName="from-white dark:from-gray-900"
{typingUsers}
userSuggestions={true}
channelSuggestions={true}