From 7ea7680f563da30b121258e5a7d7123185c4da2a Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 29 Jun 2026 12:59:05 -0500 Subject: [PATCH] refac --- backend/open_webui/routers/channels.py | 34 +++++++++++++++----- src/lib/components/channel/Channel.svelte | 36 +++++++++++++++------- src/lib/components/channel/Messages.svelte | 28 +++++++++-------- src/lib/components/channel/Thread.svelte | 2 ++ 4 files changed, 69 insertions(+), 31 deletions(-) diff --git a/backend/open_webui/routers/channels.py b/backend/open_webui/routers/channels.py index f3f6fd2885..459a238ba1 100644 --- a/backend/open_webui/routers/channels.py +++ b/backend/open_webui/routers/channels.py @@ -1365,19 +1365,37 @@ async def pin_channel_message( await Messages.update_is_pinned_by_id(message_id, form_data.is_pinned, user.id, db=db) message = await Messages.get_message_by_id(message_id, db=db) message_user = await Users.get_user_by_id(message.user_id, db=db) - await publish_event( - request, - EVENTS.MESSAGE_PINNED if form_data.is_pinned else EVENTS.MESSAGE_UNPINNED, - actor=user, - subject_id=message_id, subject_type='message', - data={'channel_id': id}, - ) - return MessageUserResponse( + message_data = MessageUserResponse( **{ **message.model_dump(), 'user': UserNameResponse(**message_user.model_dump()) if message_user else None, } ) + + await sio.emit( + 'events:channel', + { + 'channel_id': channel.id, + 'message_id': message.id, + 'data': { + 'type': 'message:update', + 'data': message_data.model_dump(), + }, + 'user': UserNameResponse(**user.model_dump()).model_dump(), + 'channel': channel.model_dump(), + }, + to=f'channel:{channel.id}', + ) + + await publish_event( + request, + EVENTS.MESSAGE_PINNED if form_data.is_pinned else EVENTS.MESSAGE_UNPINNED, + actor=user, + subject_id=message_id, + subject_type='message', + data={'channel_id': id}, + ) + return message_data except Exception as e: log.exception(e) raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()) diff --git a/src/lib/components/channel/Channel.svelte b/src/lib/components/channel/Channel.svelte index 77626a1016..10c2463688 100644 --- a/src/lib/components/channel/Channel.svelte +++ b/src/lib/components/channel/Channel.svelte @@ -76,6 +76,27 @@ ); }; + const pinHandler = ( + messageId: string, + pinned: boolean, + pinnedBy: string | null = pinned ? ($user?.id ?? null) : null, + pinnedAt: number | null = pinned ? Date.now() * 1000000 : null + ) => { + if (messages) { + messages = messages.map((message) => { + if (message.id === messageId) { + return { + ...message, + is_pinned: pinned, + pinned_by: pinnedBy, + pinned_at: pinnedAt + }; + } + return message; + }); + } + }; + const initHandler = async () => { if (currentId) { updateLastReadAt(currentId); @@ -305,17 +326,7 @@ { - messages = messages.map((message) => { - if (message.id === messageId) { - return { - ...message, - is_pinned: pinned - }; - } - return message; - }); - }} + onPin={pinHandler} onUpdate={async () => { channel = await getChannelById(localStorage.token, id).catch((error) => { return null; @@ -347,6 +358,7 @@ onThread={(id) => { threadId = id; }} + onPin={pinHandler} onLoad={async () => { const newMessages = await getChannelMessages( localStorage.token, @@ -406,6 +418,7 @@ { threadId = null; }} @@ -428,6 +441,7 @@ { threadId = null; }} diff --git a/src/lib/components/channel/Messages.svelte b/src/lib/components/channel/Messages.svelte index d3700ec711..250a5c6b56 100644 --- a/src/lib/components/channel/Messages.svelte +++ b/src/lib/components/channel/Messages.svelte @@ -37,6 +37,7 @@ export let onLoad: Function = () => {}; export let onReply: Function = () => {}; export let onThread: Function = () => {}; + export let onPin: Function = () => {}; let messagesLoading = false; @@ -166,24 +167,27 @@ onReply(message); }} onPin={async (message) => { + const pinned = !message.is_pinned; + const pinnedBy = pinned ? ($user?.id ?? null) : null; + const pinnedAt = pinned ? Date.now() * 1000000 : null; + messages = messages.map((m) => { if (m.id === message.id) { - m.is_pinned = !m.is_pinned; - m.pinned_by = !m.is_pinned ? null : $user?.id; - m.pinned_at = !m.is_pinned ? null : Date.now() * 1000000; + m.is_pinned = pinned; + m.pinned_by = pinnedBy; + m.pinned_at = pinnedAt; } return m; }); - const updatedMessage = await pinMessage( - localStorage.token, - message.channel_id, - message.id, - message.is_pinned - ).catch((error) => { - toast.error(`${error}`); - return null; - }); + onPin(message.id, pinned, pinnedBy, pinnedAt); + + await pinMessage(localStorage.token, message.channel_id, message.id, pinned).catch( + (error) => { + toast.error(`${error}`); + return null; + } + ); }} onThread={(id) => { onThread(id); diff --git a/src/lib/components/channel/Thread.svelte b/src/lib/components/channel/Thread.svelte index ba03f3a69f..5f6749db6c 100644 --- a/src/lib/components/channel/Thread.svelte +++ b/src/lib/components/channel/Thread.svelte @@ -18,6 +18,7 @@ export let channel = null; export let onClose = () => {}; + export let onPin = () => {}; let messages = null; let top = false; @@ -196,6 +197,7 @@ {messages} {replyToMessage} thread={true} + {onPin} onReply={async (message) => { replyToMessage = message;