From 3f267e3b134a54128c76b42640b55968b69a5556 Mon Sep 17 00:00:00 2001 From: AlacrisDevs Date: Sat, 7 Feb 2026 01:59:34 +0200 Subject: [PATCH] feat: room scoping (org/DM/other sections), unread badge on nav, highlight.js CSS --- src/lib/stores/matrix.ts | 7 + src/routes/[orgSlug]/+layout.svelte | 7 + src/routes/[orgSlug]/chat/+page.svelte | 186 +++++++++++++++++++------ src/routes/layout.css | 1 + 4 files changed, 161 insertions(+), 40 deletions(-) diff --git a/src/lib/stores/matrix.ts b/src/lib/stores/matrix.ts index 17529fb..57bb222 100644 --- a/src/lib/stores/matrix.ts +++ b/src/lib/stores/matrix.ts @@ -288,6 +288,13 @@ export const roomSummaries = derived(rooms, ($rooms): RoomSummary[] => { return summaries; }); +/** + * Total unread count across all rooms (for nav badge) + */ +export const totalUnreadCount = derived(roomSummaries, ($summaries): number => { + return $summaries.reduce((sum, room) => sum + (room.isSpace ? 0 : room.unreadCount), 0); +}); + // ============================================================================ // Messages // ============================================================================ diff --git a/src/routes/[orgSlug]/+layout.svelte b/src/routes/[orgSlug]/+layout.svelte index abfe296..e091ca9 100644 --- a/src/routes/[orgSlug]/+layout.svelte +++ b/src/routes/[orgSlug]/+layout.svelte @@ -10,6 +10,7 @@ import { hasPermission, type Permission } from "$lib/utils/permissions"; import { setContext } from "svelte"; import * as m from "$lib/paraglide/messages"; + import { totalUnreadCount } from "$lib/stores/matrix"; interface Member { id: string; @@ -126,6 +127,7 @@ href: `/${data.org.slug}/chat`, label: "Chat", icon: "chat", + badge: $totalUnreadCount > 0 ? ($totalUnreadCount > 99 ? "99+" : String($totalUnreadCount)) : null, }, // Settings requires settings.view or admin role ...(canAccess("settings.view") @@ -223,6 +225,11 @@ ? 'opacity-0 max-w-0 overflow-hidden' : 'opacity-100 max-w-[200px]'}">{item.label} + {#if item.badge} + + {item.badge} + + {/if} {/each} diff --git a/src/routes/[orgSlug]/chat/+page.svelte b/src/routes/[orgSlug]/chat/+page.svelte index 7c98f59..1e53c3f 100644 --- a/src/routes/[orgSlug]/chat/+page.svelte +++ b/src/routes/[orgSlug]/chat/+page.svelte @@ -79,15 +79,39 @@ : [], ); - const filteredRooms = $derived( + // All non-space rooms (exclude Space entries themselves from the list) + const allRooms = $derived( + $roomSummaries.filter((r) => !r.isSpace), + ); + + // Org rooms: rooms that belong to any Space + const orgRooms = $derived( + allRooms.filter((r) => r.parentSpaceId && !r.isDirect), + ); + + // DMs: direct messages (not tied to org) + const dmRooms = $derived( + allRooms.filter((r) => r.isDirect), + ); + + // Other rooms: not in a space and not a DM + const otherRooms = $derived( + allRooms.filter((r) => !r.parentSpaceId && !r.isDirect), + ); + + // Apply search filter across all sections + const filterBySearch = (rooms: typeof allRooms) => roomSearchQuery.trim() - ? $roomSummaries.filter( + ? rooms.filter( (room) => room.name.toLowerCase().includes(roomSearchQuery.toLowerCase()) || room.topic?.toLowerCase().includes(roomSearchQuery.toLowerCase()), ) - : $roomSummaries, - ); + : rooms; + + const filteredOrgRooms = $derived(filterBySearch(orgRooms)); + const filteredDmRooms = $derived(filterBySearch(dmRooms)); + const filteredOtherRooms = $derived(filterBySearch(otherRooms)); const currentMembers = $derived( $selectedRoomId ? getRoomMembers($selectedRoomId) : [], @@ -438,50 +462,132 @@ - -
- - Rooms {roomSearchQuery ? `(${filteredRooms.length})` : ""} - -
- -
-
- - + diff --git a/src/routes/layout.css b/src/routes/layout.css index 23e620d..9c3f3a5 100644 --- a/src/routes/layout.css +++ b/src/routes/layout.css @@ -1,6 +1,7 @@ @import url('https://fonts.googleapis.com/css2?family=Tilt+Warp&family=Work+Sans:wght@400;500;600;700&family=Inter:wght@400;500;600&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,400,0,0&display=swap'); @import 'tailwindcss'; +@import 'highlight.js/styles/github-dark.css'; @plugin '@tailwindcss/forms'; @plugin '@tailwindcss/typography';