Skip to content

Commit 05e79bd

Browse files
committed
enh: message reaction user names
1 parent fb6b18f commit 05e79bd

File tree

3 files changed

+63
-17
lines changed

3 files changed

+63
-17
lines changed

backend/open_webui/models/messages.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from open_webui.internal.db import Base, get_db
77
from open_webui.models.tags import TagModel, Tag, Tags
8-
from open_webui.models.users import Users, UserNameResponse
8+
from open_webui.models.users import Users, User, UserNameResponse
99
from open_webui.models.channels import Channels, ChannelMember
1010

1111

@@ -100,7 +100,7 @@ class MessageForm(BaseModel):
100100

101101
class Reactions(BaseModel):
102102
name: str
103-
user_ids: list[str]
103+
users: list[dict]
104104
count: int
105105

106106

@@ -389,17 +389,30 @@ def add_reaction_to_message(
389389

390390
def get_reactions_by_message_id(self, id: str) -> list[Reactions]:
391391
with get_db() as db:
392-
all_reactions = db.query(MessageReaction).filter_by(message_id=id).all()
392+
# JOIN User so all user info is fetched in one query
393+
results = (
394+
db.query(MessageReaction, User)
395+
.join(User, MessageReaction.user_id == User.id)
396+
.filter(MessageReaction.message_id == id)
397+
.all()
398+
)
393399

394400
reactions = {}
395-
for reaction in all_reactions:
401+
402+
for reaction, user in results:
396403
if reaction.name not in reactions:
397404
reactions[reaction.name] = {
398405
"name": reaction.name,
399-
"user_ids": [],
406+
"users": [],
400407
"count": 0,
401408
}
402-
reactions[reaction.name]["user_ids"].append(reaction.user_id)
409+
410+
reactions[reaction.name]["users"].append(
411+
{
412+
"id": user.id,
413+
"name": user.name,
414+
}
415+
)
403416
reactions[reaction.name]["count"] += 1
404417

405418
return [Reactions(**reaction) for reaction in reactions.values()]

src/lib/components/channel/Messages.svelte

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@
197197
const reaction = m.reactions.find((reaction) => reaction.name === name);
198198

199199
if (reaction) {
200-
reaction.user_ids = reaction.user_ids.filter((id) => id !== $user?.id);
201-
reaction.count = reaction.user_ids.length;
200+
reaction.users = reaction.users.filter((u) => u.id !== $user?.id);
201+
reaction.count = reaction.users.length;
202202

203203
if (reaction.count === 0) {
204204
m.reactions = m.reactions.filter((r) => r.name !== name);
@@ -224,12 +224,12 @@
224224
const reaction = m.reactions.find((reaction) => reaction.name === name);
225225

226226
if (reaction) {
227-
reaction.user_ids.push($user?.id);
228-
reaction.count = reaction.user_ids.length;
227+
reaction.users.push({ id: $user?.id, name: $user?.name });
228+
reaction.count = reaction.users.length;
229229
} else {
230230
m.reactions.push({
231231
name: name,
232-
user_ids: [$user?.id],
232+
users: [{ id: $user?.id, name: $user?.name }],
233233
count: 1
234234
});
235235
}

src/lib/components/channel/Messages/Message.svelte

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,44 @@
398398
<div>
399399
<div class="flex items-center flex-wrap gap-y-1.5 gap-1 mt-1 mb-2">
400400
{#each message.reactions as reaction}
401-
<Tooltip content={`:${reaction.name}:`}>
401+
<Tooltip
402+
content={$i18n.t('{{NAMES}} reacted with {{REACTION}}', {
403+
NAMES: reaction.users
404+
.reduce((acc, u, idx) => {
405+
const name = u.id === $user?.id ? $i18n.t('You') : u.name;
406+
const total = reaction.users.length;
407+
408+
// First three names always added normally
409+
if (idx < 3) {
410+
const separator =
411+
idx === 0
412+
? ''
413+
: idx === Math.min(2, total - 1)
414+
? ` ${$i18n.t('and')} `
415+
: ', ';
416+
return `${acc}${separator}${name}`;
417+
}
418+
419+
// More than 4 → "and X others"
420+
if (idx === 3 && total > 4) {
421+
return (
422+
acc +
423+
` ${$i18n.t('and {{COUNT}} others', {
424+
COUNT: total - 3
425+
})}`
426+
);
427+
}
428+
429+
return acc;
430+
}, '')
431+
.trim(),
432+
REACTION: `:${reaction.name}:`
433+
})}
434+
>
402435
<button
403-
class="flex items-center gap-1.5 transition rounded-xl px-2 py-1 cursor-pointer {reaction.user_ids.includes(
404-
$user?.id
405-
)
436+
class="flex items-center gap-1.5 transition rounded-xl px-2 py-1 cursor-pointer {reaction.users
437+
.map((u) => u.id)
438+
.includes($user?.id)
406439
? ' bg-blue-300/10 outline outline-blue-500/50 outline-1'
407440
: 'bg-gray-300/10 dark:bg-gray-500/10 hover:outline hover:outline-gray-700/30 dark:hover:outline-gray-300/30 hover:outline-1'}"
408441
on:click={() => {
@@ -413,9 +446,9 @@
413446
>
414447
<Emoji shortCode={reaction.name} />
415448

416-
{#if reaction.user_ids.length > 0}
449+
{#if reaction.users.length > 0}
417450
<div class="text-xs font-medium text-gray-500 dark:text-gray-400">
418-
{reaction.user_ids?.length}
451+
{reaction.users?.length}
419452
</div>
420453
{/if}
421454
</button>

0 commit comments

Comments
 (0)