Skip to content

Conversation

@rajveermalviya
Copy link
Member

Fixes: #1717

Comment on lines 115 to 123
return MessageListPage.buildRoute(
return MaterialAccountWidgetRoute(
accountId: account.id,
// TODO(#1565): Open at specific message, not just conversation
narrow: data.narrow);
page: Builder(builder: (context) {
final store = PerAccountStoreWidget.of(context);
var narrow = data.narrow;
if (narrow is TopicNarrow) {
narrow = narrow.processTopicLikeServer(
zulipFeatureLevel: store.zulipFeatureLevel,
realmEmptyTopicDisplayName: store.realmEmptyTopicDisplayName);
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I see. The normalization is a bit sticky to do at this spot, because when this method is running we don't yet have a per-account store. (In particular the app may have really not yet loaded the data from the server.) So we don't know realmEmptyTopicDisplayName, and have to make a route before we've done the normalization.

I think it'd be best to let this continue to use a proper MessageListPage route, though, and let MessageListPage or MessageList take the responsibility for normalizing the narrow. They already have the capability to do something similar, because the initial fetch might discover the topic has been moved. That's even later than the point where we have the store and can do this normalization.

Specifically I think _MessageListState.onNewStore looks like a good place to handle this.

@rajveermalviya rajveermalviya force-pushed the pr-msglist-general-chat branch from 7f63f71 to 0893924 Compare July 18, 2025 22:56
// Normalize topic name if this is a TopicNarrow. See #1717.
var narrow = widget.narrow;
if (narrow is TopicNarrow) {
narrow = narrow.processTopicLikeServer(
Copy link
Member

Choose a reason for hiding this comment

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

This should also notify the MessageListPage about the change.

In particular that will cause the app bar to put "general chat" in italics.

Copy link
Member Author

Choose a reason for hiding this comment

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

We already notify (albeit a bit later) as a side effect of model.addListener(_modelChanged) below.
If we want to do it here we would need to use something like, because ancestor calls setState in onNarrowChanged:

      SchedulerBinding.instance.scheduleFrameCallback((_) {
        widget.onNarrowChanged(narrow);
      });

Copy link
Member

Choose a reason for hiding this comment

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

I see. Yeah, I think that would be better — that will make sure it happens for the next frame, rather than waiting until the model updates for some other reason.

That explicit approach is also good because it means a reader of this code doesn't have to wonder about how and when the change makes it to the page widget.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

Copy link
Member

Choose a reason for hiding this comment

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

(In manual testing, I tried commenting that call back out to see the effect — the page ends up continuing to show the old value until the message list finishes fetching the initial messages from the server. That means "general chat" isn't in italics; and a bit more substantively, any applicable topic-visibility icon is missing.

So indeed calling onNarrowChanged explicitly here prevents a user-visible glitch, in addition to making it easier for a reader to become confident that things work.)

@rajveermalviya rajveermalviya force-pushed the pr-msglist-general-chat branch 2 times, most recently from 26f5b51 to 1e90bc5 Compare July 18, 2025 23:27
@rajveermalviya rajveermalviya marked this pull request as ready for review July 18, 2025 23:27
@rajveermalviya rajveermalviya added the integration review Added by maintainers when PR may be ready for integration label Jul 18, 2025
@rajveermalviya rajveermalviya requested a review from gnprice July 18, 2025 23:28
@rajveermalviya rajveermalviya force-pushed the pr-msglist-general-chat branch from 1e90bc5 to a0e528c Compare July 18, 2025 23:38
Comment on lines 784 to 785
SchedulerBinding.instance.scheduleFrameCallback((_) {
widget.onNarrowChanged(narrow);
Copy link
Member

Choose a reason for hiding this comment

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

This is only needed if the narrow is different from its original value — let's avoid calling it when nothing changed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

@rajveermalviya rajveermalviya force-pushed the pr-msglist-general-chat branch from a0e528c to c1a8f44 Compare July 18, 2025 23:44
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 for fixing this! The logic looks good now. Two comments below.

I'll add that commit clarifying the test, and merge.

// Normalize topic name if this is a TopicNarrow. See #1717.
var narrow = widget.narrow;
if (narrow is TopicNarrow) {
narrow = narrow.processTopicLikeServer(
Copy link
Member

Choose a reason for hiding this comment

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

(In manual testing, I tried commenting that call back out to see the effect — the page ends up continuing to show the old value until the message list finishes fetching the initial messages from the server. That means "general chat" isn't in italics; and a bit more substantively, any applicable topic-visibility icon is missing.

So indeed calling onNarrowChanged explicitly here prevents a user-visible glitch, in addition to making it easier for a reader to become confident that things work.)

Comment on lines 161 to 172
testWidgets('MessageListPageState.narrow (general chat)', (tester) async {
final stream = eg.stream();
final topic = eg.defaultRealmEmptyTopicDisplayName;
final topicNarrow = eg.topicNarrow(stream.streamId, topic);
await setupMessageListPage(tester, narrow: topicNarrow,
streams: [stream],
messages: [eg.streamMessage(stream: stream, topic: topic, content: "<p>a message</p>")]);
final state = MessageListPage.ancestorOf(tester.element(find.text("a message")));
check(state.narrow).equals(eg.topicNarrow(stream.streamId, ''));
Copy link
Member

Choose a reason for hiding this comment

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

I think this test works, at the level that if we were to re-introduce this bug, the test would fail.

There's another layer of what a test needs to do to be fully successful at its job: when the test does fail in that situation, it needs to tell its story. (I go into more detail on this in the talk I gave last month at Fluttercon; hoping for the talk video to get posted soon so I can share it.) The person who's made the change needs to be able to look at the test and figure out why the test's author thought it was important for things to behave this way; they need to be able to determine whether the breakage is pointing at a real bug in their change, or just means the test needs to be updated to match their change. If they can't tell that, then it's likely they'll just edit the test to match the new (broken) behavior, and the test won't have done its job of preventing the regression.

I think this version doesn't really tell the story. It looks very much like the test above it — but that test is just testing some boring plumbing. In this test, there's a critical contrast where a piece of data (the topic name) is different at one stage from an earlier stage; and there's a reason why that particular change should happen and why it's important. The contrast is easy to miss when scanning this code; and once spotted, without the reason, it almost looks like a bug instead of an important feature.

I'll add a commit to fix this aspect up and demonstrate telling the test's story.

rajveermalviya and others added 3 commits July 18, 2025 17:12
This is a helper function around `TopicName.processLikeServer`,
where it creates a new `TopicNarrow` with the processed topic name.
@gnprice gnprice force-pushed the pr-msglist-general-chat branch from c1a8f44 to 09203d1 Compare July 19, 2025 00:13
@gnprice gnprice merged commit 09203d1 into zulip:main Jul 19, 2025
1 check failed
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.

Message list on "general chat" fails to get new messages

2 participants