Skip to content

Conversation

@chrisbobbe
Copy link
Collaborator

@chrisbobbe chrisbobbe commented Jan 30, 2026

Fixes #1272.

(This is a draft because there's an open discussion; see the "scrollable when long" screenshots and the CZO link there.)

The action sheet is offered in all four places mentioned in the issue:

It should be reachable by long-pressing any of these:

  • A DM row in the Inbox
  • A recipient header in the message list
  • The area of the message-list app bar that identifies the narrow
  • The "Direct messages" (recent DMs) page

Self-DM:

Light Dark
image image

1:1 DM:

Light Dark
image image

Group DM:

Light Dark
image image

List of users in group DM, which is scrollable when long. We might still prefer a different page for this list (#1534); see #mobile > abbreviated headings @ 💬:

Light Dark
image image

@chrisbobbe
Copy link
Collaborator Author

Updated for Alya's feedback at #mobile > abbreviated headings @ 💬:

Makes sense to me. We might want to show 4-ish lines rather than 6-ish.

Light Dark
image image

Also see Greg's messages, from #mobile > abbreviated headings @ 💬:

True, the scrollable headers give a way to have a long list there without it making the rest of the action sheet unwieldy.

I think it'd still be useful to have a separate page that lists the users, following Vlad's design as seen in the screenshot at the top of this thread. Notably that adds details like status, pronouns, email address, or whatever else we put in the two-line list item for a user.

But that can coexist (whenever we implement it) with having a header like this that shows the pills. The separate page could be accessed through an option in the action sheet, with a title like "Conversation member details" (the "details" part being what signals it's more than the header shows).

So, marking as ready for review.

@chrisbobbe chrisbobbe marked this pull request as ready for review February 6, 2026 00:38
@chrisbobbe chrisbobbe added the maintainer review PR ready for review by Zulip maintainers label Feb 6, 2026
@chrisbobbe
Copy link
Collaborator Author

(fixed an unused-import nit flagged by the analyzer)

Copy link
Member

@rajveermalviya rajveermalviya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @chrisbobbe! All LGTM, modulo one tiny nit.
Moving over to Greg's review.

]);

case DmNarrow(:var otherRecipientIds):
case DmNarrow(:var otherRecipientIds): {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unnecessary braces?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure; removed for my next revision.

@rajveermalviya rajveermalviya added integration review Added by maintainers when PR may be ready for integration and removed maintainer review PR ready for review by Zulip maintainers labels Feb 9, 2026
@chrisbobbe
Copy link
Collaborator Author

Thanks! Revision pushed.

Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Generally this looks great; small comments below.


[
if (narrow.otherRecipientIds.isEmpty)
ViewProfileButton(pageContext: context,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ViewProfileButton(pageContext: context,
ViewProfileButton(pageContext: pageContext,

?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, and I notice a few existing places we made this same mistake; I'll add a commit to fix those.

];

final header = BottomSheetHeader(
title: switch (narrow) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: call the otherRecipientIds getter once here, instead of once per case, so as to build the list just once

Suggested change
title: switch (narrow) {
title: switch (narrow.otherRecipientIds) {

In fact since there's a few other references above, probably best to pull it out as a local.

Comment on lines 1517 to 1518
group('smoke', () {
group('from inbox', () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: collapse the singleton group; and can be a bit more specific about what these tests cover:

Suggested change
group('smoke', () {
group('from inbox', () {
group('show from inbox', () {

Namely, they cover causing the action sheet to show and how it looks when shown, while the behavior of the buttons is left to other tests below.

Comment on lines 1559 to 1560
]);
await tester.tap(find.widgetWithText(UserChip, eg.otherUser.fullName));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This maybe deserves highlighting as a separate test case. But at a minimum give it a separate stanza and a comment line:

Suggested change
]);
await tester.tap(find.widgetWithText(UserChip, eg.otherUser.fullName));
]);
// Tapping a user in the header leads to their profile.
await tester.tap(find.widgetWithText(UserChip, eg.otherUser.fullName));

Comment on lines 1681 to 1685
check(findInHeader(find.text('DMs with ${eg.otherUser.fullName}')))
.findsOne();
check(store.unreads.countInDmNarrow(narrow)).equals(0);
check(findInHeader(find.text('DMs with ${eg.otherUser.fullName}')))
.findsOne();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two findInHeader checks are redundant, right?

… weren't

Topic-row UI is naturally ephemeral; it could disappear if the topic
ceases to exist, or you read all its messages (as in the Inbox),
etc., which is why we prefer not to use its BuildContext where we
could use the whole page's context instead.
Fixes zulip#1272.

While working on the design update for the Inbox page, I noticed that
we were well-prepared to implement the DM action sheet, including a
way to show the participants of a group DM in the action sheet itself.
For that, I've used a scrollable collection of user "chips" in the
action-sheet header, with avatar, presence, and name. Discussion
ongoing for whether we like this approach or prefer to put the users
list on a separate page, as in issue zulip#1534:
  https://chat.zulip.org/#narrow/channel/48-mobile/topic/abbreviated.20headings/near/2366774

In this commit, the action sheet can have up to two buttons:
- "View profile", for 1:1 DMs
- "Mark conversation as read", if there are unreads.
@chrisbobbe
Copy link
Collaborator Author

Thanks for the review! Revision pushed.

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

Labels

integration review Added by maintainers when PR may be ready for integration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Action sheet for a DM conversation

3 participants