-
Notifications
You must be signed in to change notification settings - Fork 320
"Copy link to topic" in topic action sheet #1762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! This looks good; one small comment on the icon in the action sheet.
For the tests, let's include a test for the pre-271 behavior of omitting "/with/" (see resolveApiNarrowForServer
).
lib/widgets/action_sheet.dart
Outdated
|
||
final TopicNarrow narrow; | ||
|
||
@override IconData get icon => Icons.link; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I notice that this is Icons.link
instead of ZulipIcons.link
. Do we have a custom icon we can use here?
…Ah I think we do. Here's the SVG: https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=544-22131&p=f&m=dev
I see it being used for "Copy link to channel" in Figma: https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=6326-96513&m=dev
Would you add a prep commit that adds that new custom icon, and another commit that changes the one existing Icons.link
(in "Copy link to message") to use the new icon?
Would it be a follow-up to do the equivalent of zulip/zulip#29136? |
fbae311
to
0ec065a
Compare
Thanks @chrisbobbe for the review! New revision pushed, with tests included. Also added the new "link" icon, with screenshots updated. PTAL. |
Yeah, I think doing that as a follow-up would be the better option and will make it easy to get this PR merged sooner. |
0ec065a
to
abe1afb
Compare
e6fde8e
to
2454342
Compare
@chrisbobbe Pushed a new revision with the small changes you suggested in today's call. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks great! Just small comments below, and I see you've already updated the lastOrNull
commit as discussed on our call today.
if (optionButtons.isEmpty) { | ||
// TODO(a11y): This case makes a no-op gesture handler; as a consequence, | ||
// we're presenting some UI (to people who use screen-reader software) as | ||
// though it offers a gesture interaction that it doesn't meaningfully | ||
// offer, which is confusing. The solution here is probably to remove this | ||
// is-empty case by having at least one button that's always present, | ||
// such as "copy link to topic". | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
lib/widgets/action_sheet.dart
Outdated
} | ||
optionButtons.add(CopyTopicLinkButton( | ||
narrow: TopicNarrow(channelId, topic, | ||
// TODO(#1499): use the/a max message id of the topic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there still a TODO here? A previous commit started using lastOrNull
of a list of message IDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think we will still need that TODO as the previous commit partially addressed the "max message id" case and did it only for when the topic action sheet is opened through the app bar title (it's still partial becuase the last message of topic list view is still not gauranteed to be the most recent message of topic). Then for other places where the sheet is opened from, like through the recipient header or in inbox view (which currently don't pass the max message id), the best option will be to get the most recent message id from a central place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think no further change is actually needed in this direction.
- The recipient header uses the message ID of the message directly under it. When that's how the user got to the topic action sheet, having the /with/ operand point to that message seems fine and good — it means the link will continue to link to the conversation that that message belongs to, if things get split up.
- The inbox uses the latest unread message ID in the conversation, right? When there are any unreads, the latest unread will almost always be the latest message. In the unusual situations where it isn't, and if the latest (but not unread) message later gets split to a different conversation from the latest unread, I'm not sure which one would be better for the link to point to.
test/widgets/action_sheet_test.dart
Outdated
} | ||
|
||
group('copies topic link to clipboard', () { | ||
testWidgets('FL >= 271 -> link contains "with" operator', (tester) async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: When there's a pair of tests for "legacy" vs. "current" behavior, I like to consider the "current" behavior as boring/default/unmarked, so for example naming the test like
testWidgets('copies message link to clipboard', (tester) async {
, and consider the "legacy" one as interesting/unusual/marked:
testWidgets('FL < 271 -> link doesn\'t contain "with" operator', (tester) async {
In the future, when we stop supporting servers with the legacy behavior, "message link" will always include "with" in its meaning, and when we clear out the backwards-compatibility code and its corresponding test, the remaining test won't need any changes to make it look natural.
test/widgets/action_sheet_test.dart
Outdated
final expectedLink = narrowLink(store, | ||
TopicNarrow(someChannel.streamId, TopicName(someTopic), with_: message.id) | ||
).toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a quick check(expectedLink.toString().contains('with')).isTrue()
, and isFalse
in the "FL < 271" test? Just to satisfy a reader that narrowLink
handles the feature-level condition correctly and they don't need to check that detail in its implementation or tests.
(No need for a TODO to remove that check in the default/current test when clearing out backwards-compatibility code; it won't be as necessary in that future, but it's just one line so the cost is pretty minimal.)
2454342
to
c82a5fb
Compare
Thanks @chrisbobbe for the review. New changes pushed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, LGTM! Marking for Greg's review.
In the next commit(s), when creating topic permalinks, we try to use max message id of the topic, if possible. If we cannot find the max message id, then I think better to use a message id near to max message id. Related CZO discussions: https://chat.zulip.org/#narrow/channel/101-design/topic/redirects.20from.20near.20links/near/1460694 https://chat.zulip.org/#narrow/channel/101-design/topic/redirects.20from.20near.20links/near/1774403
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sm-sayedi for taking care of this, and @chrisbobbe for the previous reviews! Just small comments below.
test/widgets/action_sheet_test.dart
Outdated
).toString(); | ||
check(expectedLink.toString().contains('/with/')).isTrue(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: redundant toString
I'd probably remove the first one, and let expectedLink be a Uri
object.
test/widgets/action_sheet_test.dart
Outdated
await prepare(channel: someChannel, topic: someTopic, | ||
zulipFeatureLevel: 270); | ||
await showFromRecipientHeader(tester, message: message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this test uses showFromRecipientHeader while its counterpart above uses showFromAppBar?
Because these two are meant to demonstrate a contrast in the behavior depending on the feature level, it's best if their setup is all the same except for the feature level.
lib/widgets/action_sheet.dart
Outdated
} | ||
optionButtons.add(CopyTopicLinkButton( | ||
narrow: TopicNarrow(channelId, topic, | ||
// TODO(#1499): use the/a max message id of the topic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think no further change is actually needed in this direction.
- The recipient header uses the message ID of the message directly under it. When that's how the user got to the topic action sheet, having the /with/ operand point to that message seems fine and good — it means the link will continue to link to the conversation that that message belongs to, if things get split up.
- The inbox uses the latest unread message ID in the conversation, right? When there are any unreads, the latest unread will almost always be the latest message. In the unusual situations where it isn't, and if the latest (but not unread) message later gets split to a different conversation from the latest unread, I'm not sure which one would be better for the link to point to.
5b2474f
to
8792876
Compare
Thanks @gnprice for the review. New revision pushed. PTAL. |
Thanks! Looks good; merging. |
Screenshots
Screen recording
Screen.Recording.2025-07-29.at.1.10.16.AM.mov
Fixes: #792