detached 4f91146

fix: remove unused imports and fix svelte reactivity issues

commit
4f91146eca10aeead46375092e19e1bccd821e45
author
bnema · · 2026-01-18 20:57 UTC
parent
81f4cf8
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +17 -20
M src/lib/components/chat-room.svelte +15 -17
@@ -96,14 +96,15 @@
9696
9797 // Merge paginated messages with live subscription data
9898 const allMessages = $derived.by<EnrichedMessage[]>(() => {
99- const merged = new Map<string, EnrichedMessage>();
99+ // Using object for deduplication (avoiding Map for svelte reactivity compliance)
100+ const merged: Record<string, EnrichedMessage> = {};
100101 for (const msg of pagedMessages) {
101- merged.set(msg.id, enrichMessage(msg));
102+ merged[msg.id] = enrichMessage(msg);
102103 }
103104 for (const msg of messages) {
104- merged.set(msg.id, msg);
105+ merged[msg.id] = msg;
105106 }
106- return Array.from(merged.values()).sort((a, b) => a.timestamp - b.timestamp);
107+ return Object.values(merged).sort((a, b) => a.timestamp - b.timestamp);
107108 });
108109
109110 // Loading and error states from Convex
@@ -127,12 +128,7 @@
127128
128129 // ============ USER STATE ============
129130
130- let currentUser = $state<SafeUser | null>(null);
131-
132- // Sync current user from chatState
133- $effect(() => {
134- currentUser = chatState.getCurrentUser();
135- });
131+ const currentUser = $derived(chatState.getCurrentUser());
136132
137133 // ============ WINDOW STATE ============
138134
@@ -393,13 +389,15 @@
393389 const currentScrollTop = chatArea.scrollTop;
394390
395391 try {
396- const params = new URLSearchParams({
397- before: oldestMessageTimestamp?.toString() || '',
398- roomId: roomId
399- });
400- if (!currentUser) params.append('public', 'true');
401-
402- const response = await fetch(`/api/chat/messages?${params}`);
392+ // Build query string manually to avoid URLSearchParams (svelte reactivity compliance)
393+ const queryParts = [
394+ `before=${encodeURIComponent(oldestMessageTimestamp?.toString() || '')}`,
395+ `roomId=${encodeURIComponent(roomId)}`
396+ ];
397+ if (!currentUser) queryParts.push('public=true');
398+ const queryString = queryParts.join('&');
399+
400+ const response = await fetch(`/api/chat/messages?${queryString}`);
403401
404402 if (response.ok) {
405403 const data = await response.json();
@@ -96,14 +96,15 @@
96 96
97 // Merge paginated messages with live subscription data97 // Merge paginated messages with live subscription data
98 const allMessages = $derived.by<EnrichedMessage[]>(() => {98 const allMessages = $derived.by<EnrichedMessage[]>(() => {
99- const merged = new Map<string, EnrichedMessage>();99+ // Using object for deduplication (avoiding Map for svelte reactivity compliance)
100+ const merged: Record<string, EnrichedMessage> = {};
100 for (const msg of pagedMessages) {101 for (const msg of pagedMessages) {
101- merged.set(msg.id, enrichMessage(msg));102+ merged[msg.id] = enrichMessage(msg);
102 }103 }
103 for (const msg of messages) {104 for (const msg of messages) {
104- merged.set(msg.id, msg);105+ merged[msg.id] = msg;
105 }106 }
106- return Array.from(merged.values()).sort((a, b) => a.timestamp - b.timestamp);107+ return Object.values(merged).sort((a, b) => a.timestamp - b.timestamp);
107 });108 });
108 109
109 // Loading and error states from Convex110 // Loading and error states from Convex
@@ -127,12 +128,7 @@
127 128
128 // ============ USER STATE ============129 // ============ USER STATE ============
129 130
130- let currentUser = $state<SafeUser | null>(null);131+ const currentUser = $derived(chatState.getCurrentUser());
131-
132- // Sync current user from chatState
133- $effect(() => {
134- currentUser = chatState.getCurrentUser();
135- });
136 132
137 // ============ WINDOW STATE ============133 // ============ WINDOW STATE ============
138 134
@@ -393,13 +389,15 @@
393 const currentScrollTop = chatArea.scrollTop;389 const currentScrollTop = chatArea.scrollTop;
394 390
395 try {391 try {
396- const params = new URLSearchParams({392+ // Build query string manually to avoid URLSearchParams (svelte reactivity compliance)
397- before: oldestMessageTimestamp?.toString() || '',393+ const queryParts = [
398- roomId: roomId394+ `before=${encodeURIComponent(oldestMessageTimestamp?.toString() || '')}`,
399- });395+ `roomId=${encodeURIComponent(roomId)}`
400- if (!currentUser) params.append('public', 'true');396+ ];
401-397+ if (!currentUser) queryParts.push('public=true');
402- const response = await fetch(`/api/chat/messages?${params}`);398+ const queryString = queryParts.join('&');
399+
400+ const response = await fetch(`/api/chat/messages?${queryString}`);
403 401
404 if (response.ok) {402 if (response.ok) {
405 const data = await response.json();403 const data = await response.json();
M src/routes/+page.server.ts +1 -2
@@ -3,8 +3,7 @@ import { validateSessionToken } from '$lib/api/session.server';
33 import {
44 DEFAULT_TEXT_STYLE,
55 DEFAULT_USER_PREFERENCES,
6- type TextStyle,
7- type UserTextPreferences
6+ type TextStyle
87 } from '$lib/types/text-formatting';
98 import convex from '$lib/db/convex.server';
109
@@ -3,8 +3,7 @@ import { validateSessionToken } from '$lib/api/session.server';
3 import {3 import {
4 DEFAULT_TEXT_STYLE,4 DEFAULT_TEXT_STYLE,
5 DEFAULT_USER_PREFERENCES,5 DEFAULT_USER_PREFERENCES,
6- type TextStyle,6+ type TextStyle
7- type UserTextPreferences
8 } from '$lib/types/text-formatting';7 } from '$lib/types/text-formatting';
9 import convex from '$lib/db/convex.server';8 import convex from '$lib/db/convex.server';
10 9
M src/routes/api/chat/messages/+server.ts +1 -1
@@ -1,4 +1,4 @@
1-import { messages, chatRooms, users } from '$lib/db/convex.server';
1+import { messages } from '$lib/db/convex.server';
22 import { getDefaultChatRoomId } from '$lib/utils/chat.server';
33 import type { Message } from '$lib/types/chat';
44 import type { SendMessageResponse, GetMessagesResponse } from '$lib/types/payloads';
@@ -1,4 +1,4 @@
1-import { messages, chatRooms, users } from '$lib/db/convex.server';1+import { messages } from '$lib/db/convex.server';
2 import { getDefaultChatRoomId } from '$lib/utils/chat.server';2 import { getDefaultChatRoomId } from '$lib/utils/chat.server';
3 import type { Message } from '$lib/types/chat';3 import type { Message } from '$lib/types/chat';
4 import type { SendMessageResponse, GetMessagesResponse } from '$lib/types/payloads';4 import type { SendMessageResponse, GetMessagesResponse } from '$lib/types/payloads';

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 3

Tags 8

↑↓ moveenter openesc close