Skip to content

Commit 2f4425f

Browse files
gnpricePIG208
andcommitted
compose: Omit "(no topic)" from hint when not allowed to send there
Previously, "Message #stream > (no topic)" would appear as the hint text when the topic input is empty but mandatory. Now, it is shown as "Message #stream" instead, since the "(no topic)" isn't allowed when topics are mandatory. Co-authored-by: Zixuan James Li <[email protected]>
1 parent 9d0df65 commit 2f4425f

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

lib/widgets/compose_box.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,15 @@ class _StreamContentInputState extends State<_StreamContentInput> {
579579
super.dispose();
580580
}
581581

582-
/// The topic name to use in the hint text.
583-
TopicName _hintTopic() {
582+
/// The topic name to show in the hint text, or null to show no topic.
583+
TopicName? _hintTopic() {
584+
if (widget.controller.topic.isTopicVacuous) {
585+
if (widget.controller.topic.mandatory) {
586+
// The chosen topic can't be sent to, so don't show it.
587+
return null;
588+
}
589+
}
590+
584591
return TopicName(widget.controller.topic.textNormalized);
585592
}
586593

@@ -591,12 +598,13 @@ class _StreamContentInputState extends State<_StreamContentInput> {
591598

592599
final streamName = store.streams[widget.narrow.streamId]?.name
593600
?? zulipLocalizations.unknownChannelName;
594-
final hintDestination =
601+
final hintTopic = _hintTopic();
602+
final hintDestination = hintTopic == null
595603
// No i18n of this use of "#" and ">" string; those are part of how
596604
// Zulip expresses channels and topics, not any normal English punctuation,
597605
// so don't make sense to translate. See:
598606
// https://github.com/zulip/zulip-flutter/pull/1148#discussion_r1941990585
599-
'#$streamName > ${_hintTopic().displayName}';
607+
? '#$streamName' : '#$streamName > ${hintTopic.displayName}';
600608

601609
return _ContentInput(
602610
narrow: widget.narrow,

test/widgets/compose_box_test.dart

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,13 @@ void main() {
326326

327327
Future<void> prepare(WidgetTester tester, {
328328
required Narrow narrow,
329+
bool? mandatoryTopics,
329330
}) async {
330331
await prepareComposeBox(tester,
331332
narrow: narrow,
332333
otherUsers: [eg.otherUser, eg.thirdUser],
333-
streams: [channel]);
334+
streams: [channel],
335+
mandatoryTopics: mandatoryTopics);
334336
}
335337

336338
/// This checks the input's configured hint text without regard to whether
@@ -351,17 +353,56 @@ void main() {
351353
.decoration.isNotNull().hintText.equals(contentHintText);
352354
}
353355

354-
group('to ChannelNarrow', () {
356+
group('to ChannelNarrow, topics not mandatory', () {
357+
final narrow = ChannelNarrow(channel.streamId);
358+
355359
testWidgets('with empty topic', (tester) async {
356-
await prepare(tester, narrow: ChannelNarrow(channel.streamId));
360+
await prepare(tester, narrow: narrow, mandatoryTopics: false);
361+
checkComposeBoxHintTexts(tester,
362+
topicHintText: 'Topic',
363+
contentHintText: 'Message #${channel.name} > (no topic)');
364+
});
365+
366+
testWidgets('with non-empty but vacuous topic', (tester) async {
367+
await prepare(tester, narrow: narrow, mandatoryTopics: false);
368+
await enterTopic(tester, narrow: narrow, topic: '(no topic)');
369+
await tester.pump();
357370
checkComposeBoxHintTexts(tester,
358371
topicHintText: 'Topic',
359372
contentHintText: 'Message #${channel.name} > (no topic)');
360373
});
361374

362375
testWidgets('with non-empty topic', (tester) async {
363-
final narrow = ChannelNarrow(channel.streamId);
364-
await prepare(tester, narrow: narrow);
376+
await prepare(tester, narrow: narrow, mandatoryTopics: false);
377+
await enterTopic(tester, narrow: narrow, topic: 'new topic');
378+
await tester.pump();
379+
checkComposeBoxHintTexts(tester,
380+
topicHintText: 'Topic',
381+
contentHintText: 'Message #${channel.name} > new topic');
382+
});
383+
});
384+
385+
group('to ChannelNarrow, mandatory topics', () {
386+
final narrow = ChannelNarrow(channel.streamId);
387+
388+
testWidgets('with empty topic', (tester) async {
389+
await prepare(tester, narrow: narrow, mandatoryTopics: true);
390+
checkComposeBoxHintTexts(tester,
391+
topicHintText: 'Topic',
392+
contentHintText: 'Message #${channel.name}');
393+
});
394+
395+
testWidgets('with non-empty but vacuous topic', (tester) async {
396+
await prepare(tester, narrow: narrow, mandatoryTopics: true);
397+
await enterTopic(tester, narrow: narrow, topic: '(no topic)');
398+
await tester.pump();
399+
checkComposeBoxHintTexts(tester,
400+
topicHintText: 'Topic',
401+
contentHintText: 'Message #${channel.name}');
402+
});
403+
404+
testWidgets('with non-empty topic', (tester) async {
405+
await prepare(tester, narrow: narrow, mandatoryTopics: true);
365406
await enterTopic(tester, narrow: narrow, topic: 'new topic');
366407
await tester.pump();
367408
checkComposeBoxHintTexts(tester,

0 commit comments

Comments
 (0)