detached cf1cd5d

Merge pull request #2 from pdraim/staging

Fix styling not being saved and UI layout
commit
cf1cd5d88a80e5f7a83ebb50f80543e0170f1623
author
pdraim · · 2025-07-03 20:59 UTC
committer
GitHub · · 2025-07-03 20:59 UTC
merge of
2b8397d + bc42573 · diff against the first parent
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
4 files · +28 -5
M package.json +1 -1
@@ -1,7 +1,7 @@
11 {
22 "name": "pdraim",
33 "private": true,
4- "version": "0.2.0",
4+ "version": "0.2.1",
55 "type": "module",
66 "engines": {
77 "node": ">=22.13.0"
@@ -1,7 +1,7 @@
1 {1 {
2 "name": "pdraim",2 "name": "pdraim",
3 "private": true,3 "private": true,
4- "version": "0.2.0",4+ "version": "0.2.1",
5 "type": "module",5 "type": "module",
6 "engines": {6 "engines": {
7 "node": ">=22.13.0"7 "node": ">=22.13.0"
M src/lib/components/chat-room.svelte +10 -2
@@ -575,7 +575,9 @@ function handleLoginSuccess() {
575575 }}>
576576 <span class="nickname pointer-events-none">{message.user.nickname}:</span>
577577 </Tooltip>
578- <FormattedMessage {message} allowFormatting={true} />
578+ <span class="message-content">
579+ <FormattedMessage {message} allowFormatting={true} />
580+ </span>
579581 {/if}
580582 </div>
581583 {/each}
@@ -674,7 +676,7 @@ function handleLoginSuccess() {
674676 <style>
675677 .chat-area, .users-list {
676678 font-size: 1rem;
677- font-family: "Pixelated MS Sans Serif", Arial, Verdana, Tahoma, sans-serif;
679+ font-family: Arial, "Pixelated MS Sans Serif", Verdana, Tahoma, sans-serif;
678680 }
679681
680682 input:not(.styled-input) {
@@ -734,6 +736,12 @@ function handleLoginSuccess() {
734736 font-weight: bold;
735737 color: #2d31a6;
736738 cursor: help;
739+ flex-shrink: 0;
740+ }
741+
742+ .message-content {
743+ flex: 1;
744+ min-width: 0;
737745 }
738746
739747 .message .content {
@@ -575,7 +575,9 @@ function handleLoginSuccess() {
575 }}>575 }}>
576 <span class="nickname pointer-events-none">{message.user.nickname}:</span>576 <span class="nickname pointer-events-none">{message.user.nickname}:</span>
577 </Tooltip>577 </Tooltip>
578- <FormattedMessage {message} allowFormatting={true} />578+ <span class="message-content">
579+ <FormattedMessage {message} allowFormatting={true} />
580+ </span>
579 {/if}581 {/if}
580 </div>582 </div>
581 {/each}583 {/each}
@@ -674,7 +676,7 @@ function handleLoginSuccess() {
674 <style>676 <style>
675 .chat-area, .users-list {677 .chat-area, .users-list {
676 font-size: 1rem;678 font-size: 1rem;
677- font-family: "Pixelated MS Sans Serif", Arial, Verdana, Tahoma, sans-serif;679+ font-family: Arial, "Pixelated MS Sans Serif", Verdana, Tahoma, sans-serif;
678 }680 }
679 681
680 input:not(.styled-input) {682 input:not(.styled-input) {
@@ -734,6 +736,12 @@ function handleLoginSuccess() {
734 font-weight: bold;736 font-weight: bold;
735 color: #2d31a6;737 color: #2d31a6;
736 cursor: help;738 cursor: help;
739+ flex-shrink: 0;
740+ }
741+
742+ .message-content {
743+ flex: 1;
744+ min-width: 0;
737 }745 }
738 746
739 .message .content {747 .message .content {
M src/lib/validation/text-formatting.ts +12 -1
@@ -76,6 +76,17 @@ export function validateTextStyle(style: unknown): TextStyle | null {
7676 export function sanitizeStyleData(styleData: unknown): TextStyle | undefined {
7777 if (!styleData) return undefined;
7878
79- const validated = validateTextStyle(styleData);
79+ // Handle JSON string input
80+ let parsedData: unknown = styleData;
81+ if (typeof styleData === 'string') {
82+ try {
83+ parsedData = JSON.parse(styleData);
84+ } catch (error) {
85+ console.warn('Failed to parse styleData JSON:', error);
86+ return undefined;
87+ }
88+ }
89+
90+ const validated = validateTextStyle(parsedData);
8091 return validated || undefined;
8192 }⏎̸
@@ -76,6 +76,17 @@ export function validateTextStyle(style: unknown): TextStyle | null {
76 export function sanitizeStyleData(styleData: unknown): TextStyle | undefined {76 export function sanitizeStyleData(styleData: unknown): TextStyle | undefined {
77 if (!styleData) return undefined;77 if (!styleData) return undefined;
78 78
79- const validated = validateTextStyle(styleData);79+ // Handle JSON string input
80+ let parsedData: unknown = styleData;
81+ if (typeof styleData === 'string') {
82+ try {
83+ parsedData = JSON.parse(styleData);
84+ } catch (error) {
85+ console.warn('Failed to parse styleData JSON:', error);
86+ return undefined;
87+ }
88+ }
89+
90+ const validated = validateTextStyle(parsedData);
80 return validated || undefined;91 return validated || undefined;
81 }⏎̸92 }⏎̸
M src/routes/api/chat/messages/+server.ts +5 -1
@@ -197,10 +197,14 @@ export async function POST({ request, locals }: { request: Request, locals: App.
197197 content: data.content,
198198 type: data.type || 'chat',
199199 timestamp: Date.now(),
200- styleData: validatedStyleData,
200+ styleData: validatedStyleData ? JSON.stringify(validatedStyleData) : undefined,
201201 hasFormatting: Boolean(validatedStyleData)
202202 };
203203
204+
205+ // debug style data content at this point
206+ log.debug('Style data content', { styleData: validatedStyleData });
207+
204208 // Save to DB
205209 await db.insert(messages).values(newMessage);
206210 log.debug('Message saved in DB', { messageId: newMessage.id, chatRoomId: newMessage.chatRoomId, type: newMessage.type, timestamp: newMessage.timestamp });
@@ -197,10 +197,14 @@ export async function POST({ request, locals }: { request: Request, locals: App.
197 content: data.content,197 content: data.content,
198 type: data.type || 'chat',198 type: data.type || 'chat',
199 timestamp: Date.now(),199 timestamp: Date.now(),
200- styleData: validatedStyleData,200+ styleData: validatedStyleData ? JSON.stringify(validatedStyleData) : undefined,
201 hasFormatting: Boolean(validatedStyleData)201 hasFormatting: Boolean(validatedStyleData)
202 };202 };
203 203
204+
205+ // debug style data content at this point
206+ log.debug('Style data content', { styleData: validatedStyleData });
207+
204 // Save to DB208 // Save to DB
205 await db.insert(messages).values(newMessage);209 await db.insert(messages).values(newMessage);
206 log.debug('Message saved in DB', { messageId: newMessage.id, chatRoomId: newMessage.chatRoomId, type: newMessage.type, timestamp: newMessage.timestamp });210 log.debug('Message saved in DB', { messageId: newMessage.id, chatRoomId: newMessage.chatRoomId, type: newMessage.type, timestamp: newMessage.timestamp });

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