fix: persist server mute/deafen state across reloads and prevent client bypass

Server-side: add DB persistence for voice restrictions (schema, migration,
ready payload, cleanup on leave). Client-side: fix four bugs that wiped or
bypassed server restriction state — leaveVoice() no longer clears global
restriction Sets, voice_state_update leave no longer drops amber icons,
toggleMic/toggleDeafen now guard against server restrictions, and force-mute/
deafen uses direct setState instead of fragile toggle calls.
This commit is contained in:
Jannis Braun
2026-03-09 18:36:17 +01:00
parent f6cdfe993f
commit c2ddfe0cb7
7 changed files with 236 additions and 28 deletions
+10
View File
@@ -217,3 +217,13 @@ export const joinRequests = sqliteTable('join_requests', {
createdAt: integer('created_at').notNull(),
decidedAt: integer('decided_at'),
});
export const voiceRestrictions = sqliteTable('voice_restrictions', {
spaceId: text('space_id').notNull().references(() => spaces.id, { onDelete: 'cascade' }),
userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
restrictionType: text('restriction_type').notNull(), // 'mute' | 'deafen'
moderatorId: text('moderator_id').notNull().references(() => users.id),
createdAt: integer('created_at').notNull(),
}, (table) => ({
pk: primaryKey({ columns: [table.spaceId, table.userId, table.restrictionType] }),
}));