Add user profile management: display name + avatar upload (Gitea issue #12)

Users can set a display name (shown instead of username in the message
list, room member list, TopBar, and admin Users tab) and upload a real
avatar, replacing the generated color-initial avatars everywhere a user
appears. Avatars are square-cropped and downscaled to 512px, reusing
app/storage.py's upload primitives from image uploads with a new square
option.

Two deliberate divergences from message-image handling, documented in
backend/README.md: the previous avatar file is deleted on replace/remove
(safe since it's strictly one file per user), and avatar serving is not
room-gated and uses a short cache (identity-addressed and mutable, unlike
a message image's permanent content-addressed URL).

Frontend: new ProfileModal reachable from the TopBar account menu;
AuthContext gains updateUser() so a profile change reflects instantly
everywhere without a refetch.
This commit is contained in:
2026-08-14 16:59:56 -06:00
parent c6f90d49fc
commit 8ca3e2e23d
28 changed files with 689 additions and 41 deletions
+2 -1
View File
@@ -11,7 +11,7 @@ from redis.asyncio import Redis
from starlette.middleware.sessions import SessionMiddleware
from app.config import settings
from app.routers import admin, auth, bots, health, invites, push, rooms, webhooks
from app.routers import admin, auth, bots, health, invites, push, rooms, users, webhooks
from app.ws.broadcaster import RoomBroadcaster
from app.ws.chat import router as ws_router
from app.ws.connection_manager import ConnectionManager
@@ -73,6 +73,7 @@ def create_app() -> FastAPI:
app.include_router(health.router)
app.include_router(auth.router)
app.include_router(rooms.router)
app.include_router(users.router)
app.include_router(invites.router)
app.include_router(push.router)
app.include_router(admin.router)