open-webui/src/lib/components/channel/Channel.svelte

116 lines
2.5 KiB
Svelte
Raw Normal View History

2024-12-22 11:49:24 +00:00
<script lang="ts">
2024-12-23 02:40:01 +00:00
import { getChannelMessages, sendMessage } from '$lib/apis/channels';
import { toast } from 'svelte-sonner';
import MessageInput from './MessageInput.svelte';
import Messages from './Messages.svelte';
import { socket } from '$lib/stores';
import { onDestroy, onMount, tick } from 'svelte';
2024-12-22 11:49:24 +00:00
export let id = '';
2024-12-23 02:40:01 +00:00
let scrollEnd = true;
let messagesContainerElement = null;
let top = false;
let page = 1;
let messages = null;
$: if (id) {
initHandler();
}
const initHandler = async () => {
top = false;
page = 1;
messages = null;
messages = await getChannelMessages(localStorage.token, id, page);
2024-12-23 03:28:15 +00:00
if (messages) {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
if (messages.length < 50) {
top = true;
}
2024-12-23 02:40:01 +00:00
}
};
2024-12-23 03:28:15 +00:00
const channelEventHandler = async (event) => {
console.log(event);
if (event.channel_id === id) {
const type = event?.data?.type ?? null;
const data = event?.data?.data ?? null;
if (type === 'message') {
console.log('message', data);
messages = [data, ...messages];
await tick();
if (scrollEnd) {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
}
}
}
2024-12-23 02:40:01 +00:00
};
const submitHandler = async ({ content }) => {
if (!content) {
return;
}
const res = await sendMessage(localStorage.token, id, { content: content }).catch((error) => {
toast.error(error);
return null;
});
if (res) {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
}
};
onMount(() => {
$socket?.on('channel-events', channelEventHandler);
});
onDestroy(() => {
$socket?.off('channel-events', channelEventHandler);
});
2024-12-22 11:49:24 +00:00
</script>
2024-12-23 02:40:01 +00:00
<div class="h-full md:max-w-[calc(100%-260px)] w-full max-w-full flex flex-col">
<div
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0 max-w-full z-10 scrollbar-hidden"
id="messages-container"
bind:this={messagesContainerElement}
on:scroll={(e) => {
scrollEnd =
messagesContainerElement.scrollHeight - messagesContainerElement.scrollTop <=
messagesContainerElement.clientHeight + 5;
}}
>
{#key id}
<Messages
{messages}
2024-12-23 03:28:15 +00:00
{top}
2024-12-23 02:40:01 +00:00
onLoad={async () => {
page += 1;
const newMessages = await getChannelMessages(localStorage.token, id, page);
if (newMessages.length === 0) {
top = true;
return;
}
2024-12-23 03:28:15 +00:00
messages = [...messages, ...newMessages];
2024-12-23 02:40:01 +00:00
}}
/>
{/key}
</div>
<div class=" pb-[1rem]">
<MessageInput onSubmit={submitHandler} />
</div>
</div>