feat(web): improve message UX, voice gestures, and attachments
Some checks failed
CI / test (push) Failing after 21s

This commit is contained in:
2026-03-08 10:20:52 +03:00
parent 52c41b6958
commit 6a96a99775
9 changed files with 857 additions and 212 deletions

View File

@@ -1,6 +1,8 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.media.models import Attachment
from app.messages.models import Message
async def create_attachment(
@@ -24,3 +26,23 @@ async def create_attachment(
async def get_attachment_by_id(db: AsyncSession, attachment_id: int) -> Attachment | None:
return await db.get(Attachment, attachment_id)
async def list_chat_attachments(
db: AsyncSession,
*,
chat_id: int,
limit: int = 100,
before_id: int | None = None,
) -> list[tuple[Attachment, Message]]:
stmt = (
select(Attachment, Message)
.join(Message, Message.id == Attachment.message_id)
.where(Message.chat_id == chat_id)
.order_by(Attachment.id.desc())
.limit(limit)
)
if before_id is not None:
stmt = stmt.where(Attachment.id < before_id)
result = await db.execute(stmt)
return [(row[0], row[1]) for row in result.all()]

View File

@@ -3,8 +3,8 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.auth.service import get_current_user
from app.database.session import get_db
from app.media.schemas import AttachmentCreateRequest, AttachmentRead, UploadUrlRequest, UploadUrlResponse
from app.media.service import generate_upload_url, store_attachment_metadata
from app.media.schemas import AttachmentCreateRequest, AttachmentRead, ChatAttachmentRead, UploadUrlRequest, UploadUrlResponse
from app.media.service import generate_upload_url, list_attachments_for_chat, store_attachment_metadata
from app.users.models import User
router = APIRouter(prefix="/media", tags=["media"])
@@ -25,3 +25,20 @@ async def create_attachment_metadata(
current_user: User = Depends(get_current_user),
) -> AttachmentRead:
return await store_attachment_metadata(db, user_id=current_user.id, payload=payload)
@router.get("/chats/{chat_id}/attachments", response_model=list[ChatAttachmentRead])
async def list_chat_attachments_endpoint(
chat_id: int,
limit: int = 100,
before_id: int | None = None,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> list[ChatAttachmentRead]:
return await list_attachments_for_chat(
db,
user_id=current_user.id,
chat_id=chat_id,
limit=limit,
before_id=before_id,
)

View File

@@ -1,4 +1,5 @@
from pydantic import BaseModel, ConfigDict, Field
from datetime import datetime
class UploadUrlRequest(BaseModel):
@@ -30,3 +31,13 @@ class AttachmentRead(BaseModel):
file_url: str
file_type: str
file_size: int
class ChatAttachmentRead(BaseModel):
id: int
message_id: int
sender_id: int
message_created_at: datetime
file_url: str
file_type: str
file_size: int

View File

@@ -10,7 +10,8 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.config.settings import settings
from app.media import repository
from app.media.schemas import AttachmentCreateRequest, AttachmentRead, UploadUrlRequest, UploadUrlResponse
from app.media.schemas import AttachmentCreateRequest, AttachmentRead, ChatAttachmentRead, UploadUrlRequest, UploadUrlResponse
from app.chats.service import ensure_chat_membership
from app.messages.repository import get_message_by_id
ALLOWED_MIME_TYPES = {
@@ -134,3 +135,32 @@ async def store_attachment_metadata(
await db.commit()
await db.refresh(attachment)
return AttachmentRead.model_validate(attachment)
async def list_attachments_for_chat(
db: AsyncSession,
*,
user_id: int,
chat_id: int,
limit: int = 100,
before_id: int | None = None,
) -> list[ChatAttachmentRead]:
await ensure_chat_membership(db, chat_id=chat_id, user_id=user_id)
rows = await repository.list_chat_attachments(
db,
chat_id=chat_id,
limit=max(1, min(limit, 200)),
before_id=before_id,
)
return [
ChatAttachmentRead(
id=attachment.id,
message_id=attachment.message_id,
sender_id=message.sender_id,
message_created_at=message.created_at,
file_url=attachment.file_url,
file_type=attachment.file_type,
file_size=attachment.file_size,
)
for attachment, message in rows
]