- Add role="status" and aria-label to all skeleton containers
- Refactor ChannelSidebar from conditional siblings to ternary
for consistent mutual exclusivity with MemberSidebar pattern
Content was left-aligned in the content pane, making it appear
off-center relative to the full modal. Add mx-auto to center
the max-w-[640px] wrapper within the content area, matching
Discord's centering behavior.
Replace the stale-flag-based voice re-registration in the WS ready
handler with a server-authoritative check. If the server's voiceStates
doesn't include us (server restarted, lost in-memory voiceRooms),
cleanly tear down the LiveKit session via leaveVoice() + disconnect().
If the server still knows about us (WS blip), do nothing.
- Import BITRATE_MATRIX_KBPS from shared constants
- Parse and return bitrateMatrixOverrides in rowToLimits
- Widen updateData type to accept null values
- Raise maxBitrateKbps and minBitrateKbps caps from 50 000 to 1 000 000 kbps
- Add full validation for bitrateMatrixOverrides (null to clear, key/value checks)
After creating or copying a role, the name input is now auto-focused
with text selected so the user immediately starts typing. A subtle
"Role created" banner appears until the user makes any change.
RoleEditView used useState(role.name) for draft state, but React
reuses the component instance when editingRoleId changes, ignoring
the new initial value. Adding key={editingRoleId} forces a remount,
re-initializing all draft state (name, color, permissions) correctly.
Replaces hardcoded 3-resolution/3-framerate arrays with ALL_RESOLUTIONS
and STANDARD_FRAMERATES from shared constants (540p–Native, 30–120 fps).
Adds amber warning banner when high-end options (≥1440p or ≥75 fps) are
enabled, and fixes toggleResolution to handle 'native' with correct sort.
Replace hardcoded VALID_RESOLUTIONS/VALID_FRAMERATES with shared STANDARD_RESOLUTIONS/STANDARD_FRAMERATES constants. Update rowToLimits to handle the 'native' resolution value in DB parsing, and update all PATCH validation blocks to accept the expanded resolution/framerate sets and the 'native' option.
Optimistic message used content: '' while the server normalized it to
null, causing the content-based dedup to fail and leaving both the
empty temp message and the real attachment message in the list.