This commit is contained in:
Timothy Jaeryang Baek 2024-12-22 20:28:15 -07:00
parent 5e8f3048f9
commit 0d29f31846
5 changed files with 61 additions and 39 deletions

View File

@ -28,8 +28,8 @@ class Message(Base):
data = Column(JSON, nullable=True) data = Column(JSON, nullable=True)
meta = Column(JSON, nullable=True) meta = Column(JSON, nullable=True)
created_at = Column(BigInteger) created_at = Column(BigInteger) # time_ns
updated_at = Column(BigInteger) updated_at = Column(BigInteger) # time_ns
class MessageModel(BaseModel): class MessageModel(BaseModel):
@ -72,8 +72,8 @@ class MessageTable:
"content": form_data.content, "content": form_data.content,
"data": form_data.data, "data": form_data.data,
"meta": form_data.meta, "meta": form_data.meta,
"created_at": int(time.time()), "created_at": int(time.time_ns()),
"updated_at": int(time.time()), "updated_at": int(time.time_ns()),
} }
) )
@ -95,9 +95,9 @@ class MessageTable:
all_messages = ( all_messages = (
db.query(Message) db.query(Message)
.filter_by(channel_id=channel_id) .filter_by(channel_id=channel_id)
.order_by(Message.updated_at.asc()) .order_by(Message.created_at.desc())
.limit(limit)
.offset(skip) .offset(skip)
.limit(limit)
.all() .all()
) )
return [MessageModel.model_validate(message) for message in all_messages] return [MessageModel.model_validate(message) for message in all_messages]
@ -109,9 +109,9 @@ class MessageTable:
all_messages = ( all_messages = (
db.query(Message) db.query(Message)
.filter_by(user_id=user_id) .filter_by(user_id=user_id)
.order_by(Message.updated_at.asc()) .order_by(Message.created_at.desc())
.limit(limit)
.offset(skip) .offset(skip)
.limit(limit)
.all() .all()
) )
return [MessageModel.model_validate(message) for message in all_messages] return [MessageModel.model_validate(message) for message in all_messages]
@ -124,7 +124,7 @@ class MessageTable:
message.content = form_data.content message.content = form_data.content
message.data = form_data.data message.data = form_data.data
message.meta = form_data.meta message.meta = form_data.meta
message.updated_at = int(time.time()) message.updated_at = int(time.time_ns())
db.commit() db.commit()
db.refresh(message) db.refresh(message)
return MessageModel.model_validate(message) if message else None return MessageModel.model_validate(message) if message else None

View File

@ -108,7 +108,7 @@ async def post_new_message(
{ {
"channel_id": channel.id, "channel_id": channel.id,
"message_id": message.id, "message_id": message.id,
"data": {"message": message.model_dump()}, "data": {"type": "message", "data": message.model_dump()},
}, },
to=f"channel:{channel.id}", to=f"channel:{channel.id}",
) )

View File

@ -27,13 +27,31 @@
messages = await getChannelMessages(localStorage.token, id, page); messages = await getChannelMessages(localStorage.token, id, page);
if (messages.length < 50) { if (messages) {
top = true; messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
if (messages.length < 50) {
top = true;
}
} }
}; };
const channelEventHandler = async (data) => { const channelEventHandler = async (event) => {
console.log(data); 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;
}
}
}
}; };
const submitHandler = async ({ content }) => { const submitHandler = async ({ content }) => {
@ -74,6 +92,7 @@
{#key id} {#key id}
<Messages <Messages
{messages} {messages}
{top}
onLoad={async () => { onLoad={async () => {
page += 1; page += 1;
@ -84,7 +103,7 @@
return; return;
} }
messages = [...newMessages, ...messages]; messages = [...messages, ...newMessages];
}} }}
/> />
{/key} {/key}

View File

@ -35,30 +35,28 @@
</script> </script>
{#if messages} {#if messages}
<div class="h-full w-full flex-1 flex"> <div class="w-full h-full pt-2 flex-1 flex flex-col-reverse overflow-auto">
<div class="w-full pt-2"> <div>
<div class="w-full"> {#if !top}
{#if !top} <Loader
<Loader on:visible={(e) => {
on:visible={(e) => { console.log('visible');
console.log('visible'); if (!messagesLoading) {
if (!messagesLoading) { loadMoreMessages();
loadMoreMessages(); }
} }}
}} >
> <div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2">
<div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2"> <Spinner className=" size-4" />
<Spinner className=" size-4" /> <div class=" ">Loading...</div>
<div class=" ">Loading...</div> </div>
</div> </Loader>
</Loader> {/if}
{/if}
{#each messages as message, messageIdx (message.id)} {#each messages.slice().reverse() as message, messageIdx (message.id)}
<Message {message} /> <Message {message} />
{/each} {/each}
</div>
<div class="pb-6" />
</div> </div>
</div> </div>
<div class="pb-6" />
{/if} {/if}

View File

@ -5,6 +5,8 @@
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
import { page } from '$app/stores';
import { mobile, showSidebar, user } from '$lib/stores'; import { mobile, showSidebar, user } from '$lib/stores';
import EllipsisHorizontal from '$lib/components/icons/EllipsisHorizontal.svelte'; import EllipsisHorizontal from '$lib/components/icons/EllipsisHorizontal.svelte';
@ -18,7 +20,10 @@
<div <div
bind:this={itemElement} bind:this={itemElement}
class=" w-full {className} rounded-lg flex relative group hover:bg-gray-100 dark:hover:bg-gray-900 px-2.5 py-1" class=" w-full {className} rounded-lg flex relative group hover:bg-gray-100 dark:hover:bg-gray-900 {$page
.url.pathname === `/channels/${id}`
? 'bg-gray-100 dark:bg-gray-900'
: ''} px-2.5 py-1"
> >
<a <a
class=" w-full flex justify-between" class=" w-full flex justify-between"