feat(reactions): add message reactions API and web quick reactions

This commit is contained in:
2026-03-08 09:51:18 +03:00
parent 6adb8c24d7
commit 76f008d635
10 changed files with 256 additions and 8 deletions

View File

@@ -1,8 +1,8 @@
from sqlalchemy import delete, select
from sqlalchemy import delete, func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.chats.models import ChatMember
from app.messages.models import Message, MessageHidden, MessageIdempotencyKey, MessageReceipt, MessageType
from app.messages.models import Message, MessageHidden, MessageIdempotencyKey, MessageReaction, MessageReceipt, MessageType
async def create_message(
@@ -178,3 +178,44 @@ async def create_message_receipt(
db.add(receipt)
await db.flush()
return receipt
async def get_message_reaction(db: AsyncSession, *, message_id: int, user_id: int) -> MessageReaction | None:
result = await db.execute(
select(MessageReaction)
.where(MessageReaction.message_id == message_id, MessageReaction.user_id == user_id)
.limit(1)
)
return result.scalar_one_or_none()
async def list_message_reactions(db: AsyncSession, *, message_id: int) -> list[tuple[str, int]]:
result = await db.execute(
select(MessageReaction.emoji, func.count(MessageReaction.id))
.where(MessageReaction.message_id == message_id)
.group_by(MessageReaction.emoji)
.order_by(func.count(MessageReaction.id).desc(), MessageReaction.emoji.asc())
)
return [(str(emoji), int(count)) for emoji, count in result.all()]
async def upsert_message_reaction(
db: AsyncSession,
*,
message_id: int,
user_id: int,
emoji: str,
) -> tuple[MessageReaction | None, str]:
existing = await get_message_reaction(db, message_id=message_id, user_id=user_id)
if existing and existing.emoji == emoji:
await db.delete(existing)
await db.flush()
return None, "removed"
if existing:
existing.emoji = emoji
await db.flush()
return existing, "updated"
reaction = MessageReaction(message_id=message_id, user_id=user_id, emoji=emoji)
db.add(reaction)
await db.flush()
return reaction, "added"