feat: P2-3 sort rooms, P2-5 quiet hours, P2-2 custom notification sounds

P2-3 — Sort Non-Space Rooms:
- homeRoomSort: 'recent' | 'alpha' | 'unread' setting (default 'recent')
- factoryRoomIdByUnread comparator: unread rooms first, tie-break by count
- Sort icon button in Rooms NavCategoryHeader opens PopOut menu with
  three options (Recent Activity / A→Z / Unread First), checkmark on active
- Collapsed state still filters to unread-only regardless of sort choice

P2-5 — Notification Quiet Hours:
- quietHoursEnabled / quietHoursStart / quietHoursEnd added to settings
  (defaults: false, '23:00', '08:00')
- isInQuietHours() helper handles both normal and overnight spans;
  start===end treated as zero-length window (disabled) to avoid silent no-op
- Both InviteNotifications and MessageNotifications gate notify() and
  playSound() behind the quiet-hours check
- Settings → Notifications: new Quiet Hours card with Switch + two
  <input type="time"> fields (only shown when enabled)

P2-2 — Custom Notification Sounds:
- messageSoundId / inviteSoundId settings: 'notification'|'invite'|'call'|'none'
- notificationSounds.ts: shared NOTIFICATION_SOUND_MAP (removes duplication
  between ClientNonUIFeatures and SystemNotification — code review fix)
- Audio source updated reactively via useEffect when sound ID changes
- Settings → Notifications: Message Sound + Invite Sound selects expand
  when the master sound toggle is on; each has a ▶ preview button
- playPreview() catches audio.play() rejections (code review fix)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-03 19:41:02 -04:00
parent 6d2bf9a582
commit 5ae84cbeaf
5 changed files with 416 additions and 31 deletions
+16
View File
@@ -63,6 +63,14 @@ export interface Settings {
showNotifications: boolean;
isNotificationSounds: boolean;
messageSoundId: 'notification' | 'invite' | 'call' | 'none';
inviteSoundId: 'notification' | 'invite' | 'call' | 'none';
quietHoursEnabled: boolean;
quietHoursStart: string; // "HH:MM" 24h
quietHoursEnd: string; // "HH:MM" 24h
homeRoomSort: 'recent' | 'alpha' | 'unread';
hour24Clock: boolean;
dateFormatString: string;
@@ -114,6 +122,14 @@ const defaultSettings: Settings = {
showNotifications: true,
isNotificationSounds: true,
messageSoundId: 'notification',
inviteSoundId: 'invite',
quietHoursEnabled: false,
quietHoursStart: '23:00',
quietHoursEnd: '08:00',
homeRoomSort: 'recent',
hour24Clock: false,
dateFormatString: 'D MMM YYYY',