Skip to content

Fix: hide repeated avatar and username for grouped messages#82

Draft
beezly wants to merge 3 commits intoviktorstrate:mainfrom
beezly:fix/group-sender-messages
Draft

Fix: hide repeated avatar and username for grouped messages#82
beezly wants to merge 3 commits intoviktorstrate:mainfrom
beezly:fix/group-sender-messages

Conversation

@beezly
Copy link
Contributor

@beezly beezly commented Mar 14, 2026

Summary

When multiple consecutive messages are from the same sender, the avatar and username are now only shown on the first message in the group. Timestamps remain visible on every message.

Before

preview-before

After

preview-after

Changes

  • Added shouldIncludeProfileHeader(at:) helper to TimelineViewController that checks whether the previous visible item is a message from the same sender
  • TimelineItemRowView now accepts an includeProfileHeader parameter (defaults to true)
  • Both the data source and row height measurement use the same grouping logic

@viktorstrate
Copy link
Owner

Nice fix, I've thought about doing it as well but haven't come around to it yet. When testing it though I can see that the hover actions are cut off for the row that it's inside. This is not a problem when the display name is shown since it is a part of the same row. I don't know if there is an option to allow drawing outside the rect of the row. 🤔

Screenshot 2026-03-14 at 16 36 01 Screenshot 2026-03-14 at 16 36 06

@beezly
Copy link
Contributor Author

beezly commented Mar 15, 2026

Nice find! I think the only good fix for this is going to be to float a popover. I'll work on it. Marking this as a draft for now.

@beezly beezly marked this pull request as draft March 15, 2026 22:56
beezly added 2 commits March 17, 2026 11:19
NSHostingView inside NSTableView with usesAutomaticRowHeights enters an
infinite layout loop: layout() flushes SwiftUI transactions, which
invalidate constraints, which re-enter layout. AppKit detects this and
crashes with NSGenericException.

Replace the entire auto-sizing mechanism with SelfSizingHostingView:

- sizingOptions = [] prevents the hosting view from participating in
  Auto Layout constraint solving.

- invalidateIntrinsicContentSize() is overridden to NOT call super
  (which would re-enter the constraint system) but instead schedule
  a coalesced async height update via DispatchQueue.main.async.

- measureHeight() uses a temporary NSHostingController.sizeThatFits()
  to properly measure content at the cell width, including text wrapping.

- heightOfRow returns cached heights (default 60px). noteHeightOfRows
  is called with animation duration 0 to avoid visible row resizing.

Also removes the old measurementHostingView and handleTableResize.
…same sender

Only show the profile header (avatar + username) on the first message
in a consecutive group from the same sender. Timestamps remain visible
on every message.
@beezly beezly force-pushed the fix/group-sender-messages branch 3 times, most recently from 51b7298 to 0a392fa Compare March 17, 2026 19:59
Floating panel with quick reactions (👍🎉❤️), reply, reply in thread,
and pin actions. Panel is dismissed when scrolling or resizing, and
hidden when the row top is outside the visible timeline area.
@beezly beezly force-pushed the fix/group-sender-messages branch from 0a392fa to d239d3d Compare March 17, 2026 20:06
@beezly
Copy link
Contributor Author

beezly commented Mar 17, 2026

Rebased onto #85. Hover actions are now a floating NSPanel (HoverActionsPanel) instead of the inline ZStack
overlay — this avoids the clipping issues with NSTableView row views. The panel is dismissed on scroll/resize and
hidden when the row top is outside the visible timeline. The inline hover actions code has been removed from
MessageEventView and the reactions/receipts layout simplified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants