feat: two-step registration with avatar/color picker, fix focus ring clipping

Refactor RegisterPage into a two-step flow: credentials first, then
personalization (display name, avatar upload, avatar color). Replace the
dual-panel sliding layout with conditional rendering and CSS keyframe
animations to eliminate overflow-hidden clipping of focus rings.

Supporting changes:
- Server accepts avatarColor on registration
- Auth store resets all user-scoped stores on login/register/logout
- Voice store gains resetSession() for full session cleanup
- Sync presence status to federated instances
- Propagate presence_update to socialStore regardless of origin
This commit is contained in:
Jannis Braun
2026-03-11 03:43:20 +01:00
parent 10be7a44f8
commit c8e2945c07
8 changed files with 364 additions and 84 deletions
+4 -2
View File
@@ -18,7 +18,7 @@ export async function authRoutes(app: FastifyInstance): Promise<void> {
},
},
}, async (request, reply) => {
const { username, password, displayName, homeInstance, homeUserId } = request.body;
const { username, password, displayName, avatarColor: requestedAvatarColor, homeInstance, homeUserId } = request.body;
if (!username || typeof username !== 'string') {
return reply.code(400).send({ error: 'Username is required', statusCode: 400 });
@@ -96,7 +96,9 @@ export async function authRoutes(app: FastifyInstance): Promise<void> {
const userCount = db.select().from(schema.users).all().length;
const isFirstUser = userCount === 0 && !homeInstance;
const avatarColor = AVATAR_COLORS[Math.floor(Math.random() * AVATAR_COLORS.length)];
const avatarColor = (requestedAvatarColor && (AVATAR_COLORS as readonly string[]).includes(requestedAvatarColor))
? requestedAvatarColor
: AVATAR_COLORS[Math.floor(Math.random() * AVATAR_COLORS.length)];
db.insert(schema.users).values({
id: userId,