mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-12 23:02:35 +00:00
fix: keep sticky code block headers at the top of channel scroll containers (#29836)
* fix: keep sticky code block headers at the top of channel scroll containers * fix: clip the sticky code block header to the block's rounded corners * fix: give channel scroll containers their own layer so firefox clips sticky code headers
This commit is contained in:
parent
babf08e301
commit
b38755b21c
3 changed files with 94 additions and 87 deletions
|
|
@ -94,62 +94,64 @@
|
|||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="flex flex-col gap-2 max-h-[60vh] overflow-y-auto scrollbar-thin scrollbar-thumb-gray-300 dark:scrollbar-thumb-gray-700 scrollbar-track-transparent pt-7 pb-2"
|
||||
class="max-h-[60vh] overflow-y-auto will-change-transform scrollbar-thin scrollbar-thumb-gray-300 dark:scrollbar-thumb-gray-700 scrollbar-track-transparent pb-2"
|
||||
>
|
||||
{#if pinnedMessages.length === 0}
|
||||
<div class=" text-center text-xs text-gray-500 dark:text-gray-400 py-6">
|
||||
{$i18n.t('No pinned messages')}
|
||||
</div>
|
||||
{:else}
|
||||
{#each pinnedMessages as message, messageIdx (message.id)}
|
||||
<Message
|
||||
id="pinned"
|
||||
className="rounded-xl px-2"
|
||||
{message}
|
||||
{channel}
|
||||
onPin={async (message) => {
|
||||
pinnedMessages = pinnedMessages.filter((m) => m.id !== message.id);
|
||||
onPin(message.id, !message.is_pinned);
|
||||
<div class="flex flex-col gap-2 pt-7">
|
||||
{#if pinnedMessages.length === 0}
|
||||
<div class=" text-center text-xs text-gray-500 dark:text-gray-400 py-6">
|
||||
{$i18n.t('No pinned messages')}
|
||||
</div>
|
||||
{:else}
|
||||
{#each pinnedMessages as message, messageIdx (message.id)}
|
||||
<Message
|
||||
id="pinned"
|
||||
className="rounded-xl px-2"
|
||||
{message}
|
||||
{channel}
|
||||
onPin={async (message) => {
|
||||
pinnedMessages = pinnedMessages.filter((m) => m.id !== message.id);
|
||||
onPin(message.id, !message.is_pinned);
|
||||
|
||||
const updatedMessage = await pinMessage(
|
||||
localStorage.token,
|
||||
message.channel_id,
|
||||
message.id,
|
||||
!message.is_pinned
|
||||
).catch((error) => {
|
||||
toast.error(`${error}`);
|
||||
return null;
|
||||
});
|
||||
const updatedMessage = await pinMessage(
|
||||
localStorage.token,
|
||||
message.channel_id,
|
||||
message.id,
|
||||
!message.is_pinned
|
||||
).catch((error) => {
|
||||
toast.error(`${error}`);
|
||||
return null;
|
||||
});
|
||||
|
||||
init();
|
||||
}}
|
||||
onReaction={false}
|
||||
onThread={false}
|
||||
onReply={false}
|
||||
onEdit={false}
|
||||
onDelete={false}
|
||||
/>
|
||||
|
||||
{#if messageIdx === pinnedMessages.length - 1 && !allItemsLoaded}
|
||||
<Loader
|
||||
on:visible={(e) => {
|
||||
console.log('visible');
|
||||
if (!loading) {
|
||||
page += 1;
|
||||
getPinnedMessages();
|
||||
}
|
||||
init();
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2"
|
||||
onReaction={false}
|
||||
onThread={false}
|
||||
onReply={false}
|
||||
onEdit={false}
|
||||
onDelete={false}
|
||||
/>
|
||||
|
||||
{#if messageIdx === pinnedMessages.length - 1 && !allItemsLoaded}
|
||||
<Loader
|
||||
on:visible={(e) => {
|
||||
console.log('visible');
|
||||
if (!loading) {
|
||||
page += 1;
|
||||
getPinnedMessages();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Spinner className=" size-4" />
|
||||
<div class=" ">{$i18n.t('Loading...')}</div>
|
||||
</div>
|
||||
</Loader>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
<div
|
||||
class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2"
|
||||
>
|
||||
<Spinner className=" size-4" />
|
||||
<div class=" ">{$i18n.t('Loading...')}</div>
|
||||
</div>
|
||||
</Loader>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -188,43 +188,48 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 min-h-0 w-full overflow-y-auto pt-7" bind:this={messagesContainerElement}>
|
||||
{#if messages !== null}
|
||||
<Messages
|
||||
id={threadId}
|
||||
{channel}
|
||||
{top}
|
||||
{messages}
|
||||
{replyToMessage}
|
||||
thread={true}
|
||||
{onPin}
|
||||
onReply={async (message) => {
|
||||
replyToMessage = message;
|
||||
<div
|
||||
class="flex-1 min-h-0 w-full overflow-y-auto will-change-transform"
|
||||
bind:this={messagesContainerElement}
|
||||
>
|
||||
<div class="pt-7">
|
||||
{#if messages !== null}
|
||||
<Messages
|
||||
id={threadId}
|
||||
{channel}
|
||||
{top}
|
||||
{messages}
|
||||
{replyToMessage}
|
||||
thread={true}
|
||||
{onPin}
|
||||
onReply={async (message) => {
|
||||
replyToMessage = message;
|
||||
|
||||
await tick();
|
||||
chatInputElement?.focus();
|
||||
}}
|
||||
onLoad={async () => {
|
||||
const newMessages = await getChannelThreadMessages(
|
||||
localStorage.token,
|
||||
channel.id,
|
||||
threadId,
|
||||
messages.length
|
||||
);
|
||||
await tick();
|
||||
chatInputElement?.focus();
|
||||
}}
|
||||
onLoad={async () => {
|
||||
const newMessages = await getChannelThreadMessages(
|
||||
localStorage.token,
|
||||
channel.id,
|
||||
threadId,
|
||||
messages.length
|
||||
);
|
||||
|
||||
messages = [...messages, ...newMessages];
|
||||
messages = [...messages, ...newMessages];
|
||||
|
||||
if (newMessages.length < 50) {
|
||||
top = true;
|
||||
return;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<div class="w-full flex justify-center pt-5 pb-10">
|
||||
<Spinner />
|
||||
</div>
|
||||
{/if}
|
||||
if (newMessages.length < 50) {
|
||||
top = true;
|
||||
return;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<div class="w-full flex justify-center pt-5 pb-10">
|
||||
<Spinner />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" pb-[1rem] px-2.5 w-full">
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@
|
|||
|
||||
<div>
|
||||
<div
|
||||
class="relative {className} flex flex-col rounded-2xl border border-gray-100/30 dark:border-gray-850/30 my-0.5"
|
||||
class="relative {className} flex flex-col rounded-2xl border border-gray-100/30 dark:border-gray-850/30 my-0.5 overflow-clip"
|
||||
dir="ltr"
|
||||
>
|
||||
{#if ['mermaid', 'vega', 'vega-lite'].includes(lang)}
|
||||
|
|
@ -457,7 +457,7 @@
|
|||
{/if}
|
||||
{:else}
|
||||
<div
|
||||
class="sticky {stickyButtonsClassName} left-0 right-0 py-1.5 px-3.5 gap-2 flex items-center justify-end w-full z-10 text-xs text-black dark:text-white bg-white dark:bg-black rounded-t-2xl"
|
||||
class="sticky {stickyButtonsClassName} left-0 right-0 py-1.5 px-3.5 gap-2 flex items-center justify-end w-full z-10 text-xs text-black dark:text-white bg-white dark:bg-black"
|
||||
>
|
||||
<div class="flex-1 truncate">
|
||||
<Tooltip content={lang} placement="top-start">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue