Skip to content

Polish conversation view: composer overlay, blur, and spacing#507

Merged
wesbillman merged 7 commits into
mainfrom
conversation-view
May 8, 2026
Merged

Polish conversation view: composer overlay, blur, and spacing#507
wesbillman merged 7 commits into
mainfrom
conversation-view

Conversation

@thomaspblock
Copy link
Copy Markdown
Collaborator

@thomaspblock thomaspblock commented May 8, 2026

Summary

  • Overlay the message composer (and thread reply composer) on top of the timeline with a translucent, frosted background so messages can scroll behind it without bleeding past the bottom edge.
  • Keep sticky day/date dividers behind the composer overlay so labels scroll under the frosted composer like normal timeline content.
  • Tighten composer card density (padding, toolbar row height) so the input feels less bulky.
  • Add breathing room above the reply pill so it no longer hugs media/emojis.
  • Match the thread "Jump to latest" button to the main conversation styling and lift both buttons above the composer surface.
  • Equalize bottom spacing in the thread scroll area so the last message lands at the same height above the composer as in the main view.
  • Tighten the gap between author name and message body in the main conversation rows.
  • Bump main-conversation avatars from 32px to 36px (regular messages and system join/leave/etc. rows).

Test plan

  • Smoke main channel: send messages, verify composer overlay/blur, no content peeking below composer, last message clears the composer with comfortable spacing, and date labels scroll behind the composer.
  • Open a thread, verify reply composer behaves the same and "Jump to latest" matches the main button styling/position.
  • Confirm composer with attachments, edit target, and reply target still renders correctly (no layout regressions).
  • Verify avatar size and author/body spacing look right for regular messages, system messages, bots/personas, and thread replies.
  • Run cd desktop && pnpm exec playwright test --project=smoke -g "does not shift the timeline when the composer grows".
  • Run pre-commit/pre-push hooks via git commit and git push.

thomaspblock and others added 4 commits May 7, 2026 21:45
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@thomaspblock thomaspblock requested a review from wesbillman as a code owner May 8, 2026 13:10
thomaspblock and others added 3 commits May 8, 2026 09:30
Co-authored-by: Cursor <cursoragent@cursor.com>
The composer is now an absolute overlay, so it no longer shrinks the
timeline's clientHeight when it grows. Loosen the affected boundary
assertions to match the new layout while preserving the original intent
(no scroll shift, replies auto-scroll near the top).

Co-authored-by: Cursor <cursoragent@cursor.com>
Lower the sticky day divider stacking level so timeline date labels scroll behind the overlaid composer instead of floating above it.

Co-authored-by: Cursor <cursoragent@cursor.com>
@wesbillman wesbillman merged commit 5e7f588 into main May 8, 2026
15 checks passed
@wesbillman wesbillman deleted the conversation-view branch May 8, 2026 15:50
tlongwell-block pushed a commit that referenced this pull request May 13, 2026
The iOS channel list provider was unconditionally dropping any channel
with a 'ttl' tag, which made TTL channels invisible to members even
though they appeared correctly on desktop. The filter was added when the
file was introduced (PR #507) and no comment explained why.

Meanwhile, channels_page.dart already has an _EphemeralBadge widget
ready to render TTL channels with a remaining-time indicator — that
path was dead code for the main list because the channels never made
it there.

Repro: a member of an open, kind:39000-with-ttl-tag channel could not
see it on iOS at all, while desktop showed it with the existing badge.

Fix:
1) Drop the !channel.isEphemeral guard in channels_provider.dart so
   ttl-tagged channels reach the list.
2) Parse the kind:39000 'archived' tag in ChannelData.fromEvent and
   propagate it to Channel.archivedAt.

The second change is necessary because the relay's TTL reaper auto-
archives expired ephemeral channels and republishes kind:39000 with
['archived', 'true']. Without parsing that tag, removing the
!isEphemeral guard would let expired TTL channels stay visible after
the reaper hid them. The same fix also makes user-initiated archive
state propagate correctly via the Nostr path — previously the mobile
parser ignored 'archived' entirely, so the existing
!channel.isArchived filters in channels_page.dart:275 and
channels_provider.dart:207 only worked for the JSON path.

Tests: added two regression tests in channels_provider_test.dart that
construct kind:39000 metadata events with the ttl / archived tags and
assert the resulting Channel surfaces them correctly.

Signed-off-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
tlongwell-block pushed a commit that referenced this pull request May 13, 2026
The iOS channel list provider was unconditionally dropping any channel
with a 'ttl' tag, which made TTL channels invisible to members even
though they appeared correctly on desktop. The filter was added when the
file was introduced (PR #507) and no comment explained why.

Meanwhile, channels_page.dart already has an _EphemeralBadge widget
ready to render TTL channels with a remaining-time indicator — that
path was dead code for the main list because the channels never made
it there.

Repro: a member of an open, kind:39000-with-ttl-tag channel could not
see it on iOS at all, while desktop showed it with the existing badge.

Fix:
1) Drop the !channel.isEphemeral guard in channels_provider.dart so
   ttl-tagged channels reach the list.
2) Parse the kind:39000 'archived' tag in ChannelData.fromEvent and
   propagate it to Channel.archivedAt.

The second change is necessary because the relay's TTL reaper auto-
archives expired ephemeral channels and republishes kind:39000 with
['archived', 'true']. Without parsing that tag, removing the
!isEphemeral guard would let expired TTL channels stay visible after
the reaper hid them. The same fix also makes user-initiated archive
state propagate correctly via the Nostr path — previously the mobile
parser ignored 'archived' entirely, so the existing
!channel.isArchived filters in channels_page.dart:275 and
channels_provider.dart:207 only worked for the JSON path.

Tests: added two regression tests in channels_provider_test.dart that
construct kind:39000 metadata events with the ttl / archived tags and
assert the resulting Channel surfaces them correctly.

Signed-off-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
tlongwell-block pushed a commit that referenced this pull request May 13, 2026
The iOS channel list provider was unconditionally dropping any channel
with a 'ttl' tag, which made TTL channels invisible to members even
though they appeared correctly on desktop. The filter was added when the
file was introduced (PR #507) and no comment explained why.

Meanwhile, channels_page.dart already has an _EphemeralBadge widget
ready to render TTL channels with a remaining-time indicator — that
path was dead code for the main list because the channels never made
it there.

Repro: a member of an open, kind:39000-with-ttl-tag channel could not
see it on iOS at all, while desktop showed it with the existing badge.

Fix:
1) Drop the !channel.isEphemeral guard in channels_provider.dart so
   ttl-tagged channels reach the list.
2) Parse the kind:39000 'archived' tag in ChannelData.fromEvent and
   propagate it to Channel.archivedAt.

The second change is necessary because the relay's TTL reaper auto-
archives expired ephemeral channels and republishes kind:39000 with
['archived', 'true']. Without parsing that tag, removing the
!isEphemeral guard would let expired TTL channels stay visible after
the reaper hid them. The same fix also makes user-initiated archive
state propagate correctly via the Nostr path — previously the mobile
parser ignored 'archived' entirely, so the existing
!channel.isArchived filters in channels_page.dart:275 and
channels_provider.dart:207 only worked for the JSON path.

Tests: added two regression tests in channels_provider_test.dart that
construct kind:39000 metadata events with the ttl / archived tags and
assert the resulting Channel surfaces them correctly.

Signed-off-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
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