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

143 lines
3.6 KiB
Svelte
Raw Normal View History

2024-12-22 11:49:24 +00:00
<script lang="ts">
import { toast } from 'svelte-sonner';
2024-12-23 05:24:09 +00:00
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import isToday from 'dayjs/plugin/isToday';
import isYesterday from 'dayjs/plugin/isYesterday';
dayjs.extend(relativeTime);
dayjs.extend(isToday);
dayjs.extend(isYesterday);
import { tick, getContext, onMount, createEventDispatcher } from 'svelte';
2024-12-31 07:06:34 +00:00
import { settings, user } from '$lib/stores';
2024-12-23 05:37:14 +00:00
2024-12-22 11:49:24 +00:00
import Message from './Messages/Message.svelte';
import Loader from '../common/Loader.svelte';
import Spinner from '../common/Spinner.svelte';
2024-12-31 07:06:34 +00:00
import { addReaction, deleteMessage, removeReaction, updateMessage } from '$lib/apis/channels';
2024-12-22 11:49:24 +00:00
const i18n = getContext('i18n');
2024-12-23 05:24:09 +00:00
export let channel = null;
2024-12-23 02:40:01 +00:00
export let messages = [];
export let top = false;
2024-12-22 11:49:24 +00:00
2024-12-23 02:40:01 +00:00
export let onLoad: Function = () => {};
2024-12-22 11:49:24 +00:00
let messagesLoading = false;
const loadMoreMessages = async () => {
// scroll slightly down to disable continuous loading
const element = document.getElementById('messages-container');
element.scrollTop = element.scrollTop + 100;
messagesLoading = true;
2024-12-23 02:40:01 +00:00
await onLoad();
2024-12-22 11:49:24 +00:00
2024-12-23 02:40:01 +00:00
await tick();
2024-12-22 11:49:24 +00:00
messagesLoading = false;
};
</script>
2024-12-23 02:40:01 +00:00
{#if messages}
2024-12-23 04:56:51 +00:00
{@const messageList = messages.slice().reverse()}
<div>
{#if !top}
<Loader
on:visible={(e) => {
console.log('visible');
if (!messagesLoading) {
loadMoreMessages();
}
}}
>
<div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2">
<Spinner className=" size-4" />
<div class=" ">Loading...</div>
</div>
</Loader>
2024-12-23 05:24:09 +00:00
{:else}
2024-12-23 05:37:14 +00:00
<div
2024-12-23 05:39:44 +00:00
class="px-5
2024-12-23 05:37:14 +00:00
{($settings?.widescreenMode ?? null) ? 'max-w-full' : 'max-w-5xl'} mx-auto"
>
2024-12-23 05:24:09 +00:00
{#if channel}
2024-12-27 20:24:58 +00:00
<div class="flex flex-col gap-1.5 pb-5 pt-10">
2024-12-23 05:37:14 +00:00
<div class="text-2xl font-medium capitalize">{channel.name}</div>
2024-12-23 05:24:09 +00:00
2024-12-23 05:37:14 +00:00
<div class=" text-gray-500">
2024-12-23 05:24:09 +00:00
This channel was created on {dayjs(channel.created_at / 1000000).format(
'MMMM D, YYYY'
)}. This is the very beginning of the {channel.name}
channel.
</div>
</div>
{:else}
2024-12-23 06:09:51 +00:00
<div class="flex justify-center text-xs items-center gap-2 py-5">
2024-12-23 05:24:09 +00:00
<div class=" ">Start of the channel</div>
</div>
{/if}
2024-12-23 05:37:14 +00:00
2024-12-23 05:39:44 +00:00
{#if messageList.length > 0}
<hr class=" border-gray-50 dark:border-gray-700/20 py-2.5 w-full" />
{/if}
</div>
2024-12-23 04:56:51 +00:00
{/if}
{#each messageList as message, messageIdx (message.id)}
<Message
{message}
showUserProfile={messageIdx === 0 ||
2024-12-23 04:57:32 +00:00
messageList.at(messageIdx - 1)?.user_id !== message.user_id}
2024-12-23 08:12:55 +00:00
onDelete={() => {
const res = deleteMessage(localStorage.token, message.channel_id, message.id).catch(
(error) => {
toast.error(error);
return null;
}
);
}}
onEdit={(content) => {
const res = updateMessage(localStorage.token, message.channel_id, message.id, {
content: content
}).catch((error) => {
toast.error(error);
return null;
});
}}
2024-12-31 07:06:34 +00:00
onReaction={(name) => {
if (
message.reactions
.find((reaction) => reaction.name === name)
?.user_ids?.includes($user.id) ??
false
) {
const res = removeReaction(
localStorage.token,
message.channel_id,
message.id,
name
).catch((error) => {
toast.error(error);
return null;
});
} else {
const res = addReaction(localStorage.token, message.channel_id, message.id, name).catch(
(error) => {
toast.error(error);
return null;
}
);
}
}}
2024-12-23 04:56:51 +00:00
/>
{/each}
<div class="pb-6" />
2024-12-22 11:49:24 +00:00
</div>
2024-12-23 02:40:01 +00:00
{/if}