From 35f8d58c653e71b096ff9b25a615f59d4afb1566 Mon Sep 17 00:00:00 2001 From: Thomas Petersen Date: Thu, 14 May 2026 20:42:52 -0400 Subject: [PATCH 1/5] fix(ui): expand content width and align message metadata Co-authored-by: Cursor --- .../src/features/channels/ui/ChannelPane.tsx | 2 +- .../src/features/messages/ui/DayDivider.tsx | 2 +- .../features/messages/ui/MessageComposer.tsx | 2 +- .../src/features/messages/ui/MessageRow.tsx | 129 +++++++------- .../features/messages/ui/MessageTimeline.tsx | 2 +- .../features/messages/ui/MessageTimestamp.tsx | 4 +- .../features/messages/ui/SystemMessageRow.tsx | 161 +++++++++--------- .../messages/ui/TypingIndicatorRow.tsx | 1 - desktop/src/shared/ui/ViewLoadingFallback.tsx | 4 +- web/src/features/repos/ui/RepoDetailPage.tsx | 6 +- web/src/features/repos/ui/ReposPage.tsx | 4 +- 11 files changed, 164 insertions(+), 153 deletions(-) diff --git a/desktop/src/features/channels/ui/ChannelPane.tsx b/desktop/src/features/channels/ui/ChannelPane.tsx index 93060be3a..90dd441cd 100644 --- a/desktop/src/features/channels/ui/ChannelPane.tsx +++ b/desktop/src/features/channels/ui/ChannelPane.tsx @@ -401,7 +401,7 @@ export const ChannelPane = React.memo(function ChannelPane({ showTopBorder={false} />
-
+
{hasComposerBotActivity ? (
diff --git a/desktop/src/features/messages/ui/MessageComposer.tsx b/desktop/src/features/messages/ui/MessageComposer.tsx index 0f870985c..9e08ff4be 100644 --- a/desktop/src/features/messages/ui/MessageComposer.tsx +++ b/desktop/src/features/messages/ui/MessageComposer.tsx @@ -555,7 +555,7 @@ export function MessageComposer({ aria-hidden="true" className="absolute inset-x-0 bottom-0 h-5 bg-background" /> -
+
); - const metadataNode = ( -
-
-
- -
-
+ const actionBarNode = ( +
+ +
+ ); + + const inlineMetadataNode = ( +
+ {message.pending ? (

Sending @@ -211,7 +213,6 @@ export const MessageRow = React.memo( This message has been edited ) : null} -

); @@ -281,52 +282,64 @@ export const MessageRow = React.memo(
+ {actionBarNode} {isThreadReplyLayout ? ( - <> -
- {message.pubkey ? ( - + {message.pubkey ? ( + + - - ) : ( - <> -
- {avatarNode} -
- {authorNode} - - )} -
-
- {message.personaDisplayName && - message.personaDisplayName !== message.author ? ( - - {message.personaDisplayName} - - ) : null} - {metadataNode} -
+ + + ) : ( + authorNode + )} + {inlineMetadataNode} + {message.personaDisplayName && + message.personaDisplayName !== message.author ? ( + + {message.personaDisplayName} + + ) : null}
+
{messageBodyNode}
-
{messageBodyNode}
- +
) : ( <> {message.pubkey ? ( @@ -349,7 +362,7 @@ export const MessageRow = React.memo(
{avatarNode}
)}
-
+
{message.pubkey ? ( {message.personaDisplayName} ) : null} - {metadataNode}
{messageBodyNode}
diff --git a/desktop/src/features/messages/ui/MessageTimeline.tsx b/desktop/src/features/messages/ui/MessageTimeline.tsx index 7e223a255..8f0500ed3 100644 --- a/desktop/src/features/messages/ui/MessageTimeline.tsx +++ b/desktop/src/features/messages/ui/MessageTimeline.tsx @@ -135,7 +135,7 @@ export const MessageTimeline = React.memo(function MessageTimeline({ ref={scrollContainerRef} >
diff --git a/desktop/src/features/messages/ui/MessageTimestamp.tsx b/desktop/src/features/messages/ui/MessageTimestamp.tsx index fe6ff873b..e8285d173 100644 --- a/desktop/src/features/messages/ui/MessageTimestamp.tsx +++ b/desktop/src/features/messages/ui/MessageTimestamp.tsx @@ -11,7 +11,9 @@ export function MessageTimestamp({ return ( -

{time}

+

+ {time} +

{formatFullDateTime(createdAt)} diff --git a/desktop/src/features/messages/ui/SystemMessageRow.tsx b/desktop/src/features/messages/ui/SystemMessageRow.tsx index 05fea9bd7..0bd848a68 100644 --- a/desktop/src/features/messages/ui/SystemMessageRow.tsx +++ b/desktop/src/features/messages/ui/SystemMessageRow.tsx @@ -200,7 +200,7 @@ export const SystemMessageRow = React.memo(function SystemMessageRow({ return (
@@ -211,9 +211,15 @@ export const SystemMessageRow = React.memo(function SystemMessageRow({ testId="system-message-avatar" />
-

- {description.title} -

+
+

+ {description.title} +

+ +

{description.action}

@@ -235,86 +241,77 @@ export const SystemMessageRow = React.memo(function SystemMessageRow({ ) : null}
-
-
-
- {canToggleReactions ? ( -
+ {canToggleReactions ? ( +
+
+ -
- - - - - - - - React - - - {reactionErrorMessage ? ( -
-

- {reactionErrorMessage} -

-
- ) : null} - { - void handleReactionSelect(emoji.native).finally( - () => { - setIsReactionPickerOpen(false); - }, - ); - }} - theme="auto" - previewPosition="none" - skinTonePosition="search" - set="native" - maxFrequentRows={2} - perLine={8} - /> -
-
-
-
- ) : null} + + + + + + + React + + + {reactionErrorMessage ? ( +
+

+ {reactionErrorMessage} +

+
+ ) : null} + { + void handleReactionSelect(emoji.native).finally(() => { + setIsReactionPickerOpen(false); + }); + }} + theme="auto" + previewPosition="none" + skinTonePosition="search" + set="native" + maxFrequentRows={2} + perLine={8} + /> +
+ +
-
- + ) : null}
diff --git a/desktop/src/features/messages/ui/TypingIndicatorRow.tsx b/desktop/src/features/messages/ui/TypingIndicatorRow.tsx index 2a843ad9f..cb0278c7c 100644 --- a/desktop/src/features/messages/ui/TypingIndicatorRow.tsx +++ b/desktop/src/features/messages/ui/TypingIndicatorRow.tsx @@ -91,7 +91,6 @@ export function TypingIndicatorRow({ className={cn( "flex w-full items-center gap-2", isActivityVariant && "h-full", - !isActivityVariant && "mx-auto max-w-4xl", )} >
diff --git a/desktop/src/shared/ui/ViewLoadingFallback.tsx b/desktop/src/shared/ui/ViewLoadingFallback.tsx index 491b5f845..64dbc4f2c 100644 --- a/desktop/src/shared/ui/ViewLoadingFallback.tsx +++ b/desktop/src/shared/ui/ViewLoadingFallback.tsx @@ -177,13 +177,13 @@ function ChannelLoadingBody() { return (
-
+
-
+
diff --git a/web/src/features/repos/ui/RepoDetailPage.tsx b/web/src/features/repos/ui/RepoDetailPage.tsx index 52bd17fcc..8c86ffe4b 100644 --- a/web/src/features/repos/ui/RepoDetailPage.tsx +++ b/web/src/features/repos/ui/RepoDetailPage.tsx @@ -60,7 +60,7 @@ function CopyableUrl({ url }: { url: string }) { function DetailSkeleton() { return ( -
+
@@ -181,7 +181,7 @@ export function RepoDetailPage() { if (!repo) { return ( -
+
+
{/* Main content */}
{/* Back link */} diff --git a/web/src/features/repos/ui/ReposPage.tsx b/web/src/features/repos/ui/ReposPage.tsx index 0cdadc108..0e1ecdb85 100644 --- a/web/src/features/repos/ui/ReposPage.tsx +++ b/web/src/features/repos/ui/ReposPage.tsx @@ -101,7 +101,7 @@ export function ReposPage() { if (isLoading) { return ( -
+

Repositories @@ -122,7 +122,7 @@ export function ReposPage() { } return ( -
+
{/* Main content */}
{/* Mobile-only connect button */} From ff3ee67d2f3997b13f3c0bdc6b910512d2854a2e Mon Sep 17 00:00:00 2001 From: Thomas Petersen Date: Thu, 14 May 2026 21:05:55 -0400 Subject: [PATCH 2/5] fix(ui): align home timestamps and loading skeletons Co-authored-by: Cursor --- .../src/features/home/ui/InboxDetailPane.tsx | 78 +++++++++---------- .../features/messages/ui/TimelineSkeleton.tsx | 13 ++-- desktop/src/shared/ui/ViewLoadingFallback.tsx | 15 ++-- 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/desktop/src/features/home/ui/InboxDetailPane.tsx b/desktop/src/features/home/ui/InboxDetailPane.tsx index ca76f7116..151a1f541 100644 --- a/desktop/src/features/home/ui/InboxDetailPane.tsx +++ b/desktop/src/features/home/ui/InboxDetailPane.tsx @@ -277,7 +277,7 @@ export function InboxDetailPane({
+ {canReply || onToggleReaction ? ( +
+ { + const actionBarMessage = + toActionBarMessage(message); + const remove = + actionBarMessage.reactions?.some( + (reaction) => + reaction.emoji === emoji && + reaction.reactedByCurrentUser, + ) ?? false; + return onToggleReaction( + actionBarMessage, + emoji, + remove, + ); + } + : undefined + } + onReply={ + canReply + ? () => handleSelectReplyTarget(message) + : undefined + } + reactions={message.reactions ?? []} + /> +
+ ) : null}
-
+

{message.authorLabel}

+

+ {message.fullTimestampLabel} +

{message.isSelected ? ( Inbox item ) : null} -

- {message.fullTimestampLabel} -

- {canReply || onToggleReaction ? ( -
-
- { - const actionBarMessage = - toActionBarMessage(message); - const remove = - actionBarMessage.reactions?.some( - (reaction) => - reaction.emoji === emoji && - reaction.reactedByCurrentUser, - ) ?? false; - return onToggleReaction( - actionBarMessage, - emoji, - remove, - ); - } - : undefined - } - onReply={ - canReply - ? () => handleSelectReplyTarget(message) - : undefined - } - reactions={message.reactions ?? []} - /> -
-
- ) : null}
- {skeletonRows.map((row) => ( + {skeletonRows.map((row, index) => (
- +
- - - +
+ + +
+ +
))} diff --git a/desktop/src/shared/ui/ViewLoadingFallback.tsx b/desktop/src/shared/ui/ViewLoadingFallback.tsx index 64dbc4f2c..29243f7a9 100644 --- a/desktop/src/shared/ui/ViewLoadingFallback.tsx +++ b/desktop/src/shared/ui/ViewLoadingFallback.tsx @@ -45,13 +45,16 @@ function LoadingHeaderSkeleton() { function MessageRowsSkeleton() { return ( <> - {["first", "second", "third", "fourth", "fifth"].map((row) => ( + {["first", "second", "third", "fourth", "fifth"].map((row, index) => (
- -
- - - + +
+
+ + +
+ +
))} From cc368c6b88a2fc60697c7ba1be485fa77e306cac Mon Sep 17 00:00:00 2001 From: Thomas Petersen Date: Thu, 14 May 2026 21:34:10 -0400 Subject: [PATCH 3/5] fix(desktop): keep profile button first in message rows Co-authored-by: Cursor --- desktop/src/features/messages/ui/MessageRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/src/features/messages/ui/MessageRow.tsx b/desktop/src/features/messages/ui/MessageRow.tsx index b2728ebf8..7455f1173 100644 --- a/desktop/src/features/messages/ui/MessageRow.tsx +++ b/desktop/src/features/messages/ui/MessageRow.tsx @@ -289,7 +289,6 @@ export const MessageRow = React.memo( data-message-id={message.id} data-testid="message-row" > - {actionBarNode} {isThreadReplyLayout ? (
{message.pubkey ? ( @@ -391,6 +390,7 @@ export const MessageRow = React.memo(
)} + {actionBarNode}
); From c7079ef8d87e1eb74d00ee3247b2a5ddf16e4cb7 Mon Sep 17 00:00:00 2001 From: Thomas Petersen Date: Thu, 14 May 2026 21:53:30 -0400 Subject: [PATCH 4/5] fix(desktop): preserve compact thread reply layout Co-authored-by: Cursor --- .../src/features/messages/ui/MessageRow.tsx | 63 ++++++++----------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/desktop/src/features/messages/ui/MessageRow.tsx b/desktop/src/features/messages/ui/MessageRow.tsx index 7455f1173..ff80e8589 100644 --- a/desktop/src/features/messages/ui/MessageRow.tsx +++ b/desktop/src/features/messages/ui/MessageRow.tsx @@ -290,44 +290,31 @@ export const MessageRow = React.memo( data-testid="message-row" > {isThreadReplyLayout ? ( -
- {message.pubkey ? ( - - - - ) : ( -
{avatarNode}
- )} -
-
- {message.pubkey ? ( - - - - ) : ( - authorNode - )} + {avatarNode} + {authorNode} + + + ) : ( + <> +
+ {avatarNode} +
+ {authorNode} + + )} +
{inlineMetadataNode} {message.personaDisplayName && message.personaDisplayName !== message.author ? ( @@ -336,9 +323,9 @@ export const MessageRow = React.memo( ) : null}
-
{messageBodyNode}
-
+
{messageBodyNode}
+ ) : ( <> {message.pubkey ? ( From 6b41c023dabd6a43792067b85a96bb99a02f4027 Mon Sep 17 00:00:00 2001 From: thomaspblock Date: Fri, 15 May 2026 17:10:28 -0400 Subject: [PATCH 5/5] chore(desktop): use thread-reply radius class --- desktop/src/features/messages/ui/MessageRow.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/desktop/src/features/messages/ui/MessageRow.tsx b/desktop/src/features/messages/ui/MessageRow.tsx index ff80e8589..f201f7737 100644 --- a/desktop/src/features/messages/ui/MessageRow.tsx +++ b/desktop/src/features/messages/ui/MessageRow.tsx @@ -299,7 +299,10 @@ export const MessageRow = React.memo( botIdenticonValue={message.author} >