Commit c1e86c4a3a6c
tarball2 files changed+31-1
@@ -204,6 +204,10 @@
204204
$: orderedRail = sortSpaces(railSpaces, railOverride);205205
$: pinnedRail = orderedRail.filter((s) => s.favourite);206206
$: otherRail = orderedRail.filter((s) => !s.favourite);207
+ $: unreadSpaces = spacesWithUnread($rooms, spaceParents);208
+ $: homeUnread =209
+ ($mentionsSnapshot?.unread_count ?? 0) > 0 ||210
+ $rooms.some((r) => r.direct && !r.space && r.membership === 'Joined' && roomUnread(r) > 0);207211
$: railSelected = selectedSpaceId ? topSpaceOf(selectedSpaceId, spaceParents) : null;208212
$: invites = $rooms.filter((r) => r.membership === 'Invited');209213
$: query = search.trim().toLowerCase();@@ -457,6 +461,18 @@
457461
return parents;458462
}459463
464
+ function spacesWithUnread(all: RoomSummary[], parents: Map<string, string>): Set<string> {465
+ const spaces = all.filter((r) => r.space);466
+ const ids = new Set(spaces.map((s) => s.room_id));467
+ const out = new Set<string>();468
+ for (const room of all) {469
+ if (room.space || room.membership !== 'Joined' || roomUnread(room) === 0) continue;470
+ const owners = [...room.parent_spaces, ...spaces.filter((s) => s.children.includes(room.room_id)).map((s) => s.room_id)];471
+ for (const id of owners) if (ids.has(id)) out.add(topSpaceOf(id, parents));472
+ }473
+ return out;474
+ }475
+460476
function topSpaceOf(id: string, parents: Map<string, string>): string {461477
let at = id;462478
while (parents.has(at)) at = parents.get(at)!;@@ -1741,7 +1757,7 @@
17411757
class="app"17421758
in:fade={{ duration: motionDuration(220) }}17431759
class:nav-folded={$navFolded}1744
- class:rail-folded={$railFolded && selectedRoom}1760
+ class:rail-folded={$railFolded && (selectedRoom || mentionsOpen || searchOpen)}17451761
class:members-open={membersShown}17461762
class:thread-open={threadShown}17471763
class:resizing@@ -1902,6 +1918,7 @@
19021918
type="button"19031919
class="rail-btn"19041920
class:active={selectedSpaceId === null}1921
+ class:unread={homeUnread}19051922
title="Home — all channels"19061923
aria-label="Home — all channels"19071924
aria-pressed={selectedSpaceId === null}@@ -1921,6 +1938,7 @@
19211938
class:drop-before={dropTarget?.id === space.room_id && !dropTarget.after}19221939
class:drop-after={dropTarget?.id === space.room_id && dropTarget.after}19231940
class:pinned={space.favourite}1941
+ class:unread={unreadSpaces.has(space.room_id)}19241942
title={space.name}19251943
aria-label={`Show channels in space ${space.name}`}19261944
aria-pressed={selectedSpaceId === space.room_id}@@ -228,6 +228,7 @@ input, textarea { font: inherit; }
228228
.app > .rail { grid-column: 1; grid-row: 2; }229229
.app > .sidebar { grid-column: 2; grid-row: 2; }230230
.app > .account { grid-column: 1; grid-row: 3; }231
+@media (min-width: 641px) { .app.rail-folded > .account { grid-column: 2; } }231232
.app > .chat { grid-column: 3; grid-row: 2 / 4; }232233
.app > .thread { grid-column: 4; grid-row: 2 / 4; }233234
.app > .members { grid-column: 5; grid-row: 2 / 4; }@@ -279,6 +280,17 @@ input, textarea { font: inherit; }
279280
padding: 0;280281
}281282
.rail-btn:hover { background: var(--accent); color: var(--on-accent); }283
+.rail-btn.unread { position: relative; overflow: visible; }284
+.rail-btn.unread::after {285
+ content: '';286
+ position: absolute;287
+ top: -2px; right: -2px;288
+ width: 10px; height: 10px;289
+ border-radius: 50%;290
+ background: var(--danger);291
+ box-shadow: 0 0 0 2px var(--rail-bg);292
+ pointer-events: none;293
+}282294
.rail-btn.active { background: var(--accent); color: var(--on-accent); }283295
.rail-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }284296
.rail-space { border-radius: 50%; transition: border-radius var(--pop), background var(--pop), color var(--pop), box-shadow var(--pop); }