Skip to content

Commit daf6f90

Browse files
committed
api: Make displayName nullable
Signed-off-by: Zixuan James Li <[email protected]>
1 parent 89b66a6 commit daf6f90

12 files changed

+15
-29
lines changed

lib/api/model/model.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ extension type const TopicName(String _value) {
690690
/// so that UI code can identify when it needs to represent the topic
691691
/// specially in the way prescribed for "general chat".
692692
// TODO(#1250) carry out that plan
693-
String get displayName => _value;
693+
String? get displayName => _value.isEmpty ? null : _value;
694694

695695
/// The key to use for "same topic as" comparisons.
696696
String canonicalize() => apiName.toLowerCase();

lib/model/autocomplete.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,13 +865,11 @@ class TopicAutocompleteQuery extends AutocompleteQuery {
865865
bool testTopic(PerAccountStore store, TopicName topic) {
866866
// TODO(#881): Sort by match relevance, like web does.
867867

868-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
869868
if (topic.displayName == null) {
870869
return store.realmEmptyTopicDisplayName.toLowerCase()
871870
.contains(raw.toLowerCase());
872871
}
873872
return topic.displayName != raw
874-
// ignore: unnecessary_non_null_assertion // null topic names soon to be enabled
875873
&& topic.displayName!.toLowerCase().contains(raw.toLowerCase());
876874
}
877875

lib/widgets/autocomplete.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,11 @@ class TopicAutocomplete extends AutocompleteField<TopicAutocompleteQuery, TopicA
329329
@override
330330
Widget buildItem(BuildContext context, int index, TopicAutocompleteResult option) {
331331
final Widget child;
332-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
333332
if (option.topic.displayName == null) {
334333
final store = PerAccountStoreWidget.of(context);
335334
child = Text(store.realmEmptyTopicDisplayName,
336335
style: const TextStyle(fontStyle: FontStyle.italic));
337336
} else {
338-
// ignore: unnecessary_non_null_assertion // null topic names soon to be enabled
339337
child = Text(option.topic.displayName!);
340338
}
341339

lib/widgets/compose_box.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ class ComposeTopicController extends ComposeController<TopicValidationError> {
129129
}
130130

131131
void setTopic(TopicName newTopic) {
132-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
133132
value = TextEditingValue(text: newTopic.displayName ?? '');
134133
}
135134
}
@@ -440,7 +439,6 @@ class _ContentInputState extends State<_ContentInput> with WidgetsBindingObserve
440439
color: designVariables.textInput.withFadedAlpha(0.5));
441440

442441
if (widget.destination.destination
443-
// ignore: constant_pattern_never_matches_value_type // null topic names soon to be enabled
444442
case StreamDestination(topic: TopicName(displayName: null))) {
445443
// TODO(#1285): This applies to the entire hint text; ideally we'd only
446444
// want to italize the "general chat" text, but this requires
@@ -546,7 +544,6 @@ class _StreamContentInputState extends State<_StreamContentInput> {
546544
destination: TopicNarrow(widget.narrow.streamId, topic),
547545
controller: widget.controller,
548546
hintText: zulipLocalizations.composeBoxChannelContentHint(
549-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
550547
streamName, topic.displayName ?? store.realmEmptyTopicDisplayName));
551548
}
552549
}
@@ -612,7 +609,6 @@ class _FixedDestinationContentInput extends StatelessWidget {
612609
final streamName = store.streams[streamId]?.name
613610
?? zulipLocalizations.composeBoxUnknownChannelName;
614611
return zulipLocalizations.composeBoxChannelContentHint(
615-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
616612
streamName, topic.displayName ?? store.realmEmptyTopicDisplayName);
617613

618614
case DmNarrow(otherRecipientIds: []): // The self-1:1 thread.

lib/widgets/inbox.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,15 +526,13 @@ class _TopicItem extends StatelessWidget {
526526
child: Text(
527527
style: TextStyle(
528528
fontSize: 17,
529-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
530529
fontStyle: (topic.displayName == null) ? FontStyle.italic : null,
531530
height: (20 / 17),
532531
// TODO(design) check if this is the right variable
533532
color: designVariables.labelMenuButton,
534533
),
535534
maxLines: 2,
536535
overflow: TextOverflow.ellipsis,
537-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
538536
topic.displayName ?? store.realmEmptyTopicDisplayName))),
539537
const SizedBox(width: 12),
540538
if (hasMention) const _IconMarker(icon: ZulipIcons.at_sign),

lib/widgets/message_list.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,8 @@ class MessageListAppBarTitle extends StatelessWidget {
362362
return Row(
363363
mainAxisSize: MainAxisSize.min,
364364
children: [
365-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
366365
Flexible(child: Text(topic.displayName ?? store.realmEmptyTopicDisplayName, style: TextStyle(
367366
fontSize: 13,
368-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
369367
fontStyle: (topic.displayName == null) ? FontStyle.italic : null,
370368
).merge(weightVariableTextStyle(context)))),
371369
if (icon != null)
@@ -1097,13 +1095,11 @@ class StreamMessageRecipientHeader extends StatelessWidget {
10971095
child: Row(
10981096
children: [
10991097
Flexible(
1100-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
11011098
child: Text(topic.displayName ?? store.realmEmptyTopicDisplayName,
11021099
// TODO: Give a way to see the whole topic (maybe a
11031100
// long-press interaction?)
11041101
overflow: TextOverflow.ellipsis,
11051102
style: recipientHeaderTextStyle(context).copyWith(
1106-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
11071103
fontStyle: (topic.displayName == null) ? FontStyle.italic : null,
11081104
))),
11091105
const SizedBox(width: 4),

test/api/model/model_checks.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extension MessageChecks on Subject<Message> {
4848

4949
extension TopicNameChecks on Subject<TopicName> {
5050
Subject<String> get apiName => has((x) => x.apiName, 'apiName');
51-
Subject<String> get displayName => has((x) => x.displayName, 'displayName');
51+
Subject<String?> get displayName => has((x) => x.displayName, 'displayName');
5252
}
5353

5454
extension StreamMessageChecks on Subject<StreamMessage> {

test/widgets/action_sheet_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ void main() {
209209

210210
await tester.longPress(find.descendant(
211211
of: find.byType(RecipientHeader),
212-
matching: find.text(effectiveMessage.topic.displayName)));
212+
matching: find.text(effectiveMessage.topic.displayName!)));
213213
// sheet appears onscreen; default duration of bottom-sheet enter animation
214214
await tester.pump(const Duration(milliseconds: 250));
215215
}

test/widgets/autocomplete_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ void main() {
297297
await tester.tap(find.text('Topic three'));
298298
await tester.pumpAndSettle();
299299
check(tester.widget<TextField>(topicInputFinder).controller!.text)
300-
.equals(topic3.name.displayName);
300+
.equals(topic3.name.displayName!);
301301
check(find.text('Topic one' )).findsNothing();
302302
check(find.text('Topic two' )).findsNothing();
303303
check(find.text('Topic three')).findsOne(); // shown in `_TopicInput` once
@@ -354,7 +354,7 @@ void main() {
354354
await tester.pumpAndSettle();
355355

356356
check(find.text(eg.defaultRealmEmptyTopicDisplayName)).findsOne();
357-
}, skip: true); // null topic names soon to be enabled
357+
});
358358

359359
testWidgets('match general chat in autocomplete', (tester) async {
360360
final topic = eg.getStreamTopicsEntry(name: '');
@@ -366,7 +366,7 @@ void main() {
366366
await tester.pumpAndSettle();
367367

368368
check(find.text(eg.defaultRealmEmptyTopicDisplayName)).findsOne();
369-
}, skip: true); // null topic names soon to be enabled
369+
});
370370

371371
testWidgets('autocomplete to general chat sets topic to empty string', (tester) async {
372372
final topic = eg.getStreamTopicsEntry(name: '');
@@ -381,6 +381,6 @@ void main() {
381381
await tester.tap(find.text(eg.defaultRealmEmptyTopicDisplayName));
382382
await tester.pump(Duration.zero);
383383
check(controller.value).text.equals('');
384-
}, skip: true); // null topic names soon to be enabled
384+
});
385385
});
386386
}

test/widgets/compose_box_test.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -351,15 +351,15 @@ void main() {
351351
checkComposeBoxHintTexts(tester,
352352
topicHintText: eg.defaultRealmEmptyTopicDisplayName,
353353
contentHintText: 'Message #${channel.name} > ${eg.defaultRealmEmptyTopicDisplayName}');
354-
}, skip: true); // null topic names soon to be enabled
354+
});
355355

356356
testWidgets('to ChannelNarrow with empty topic (mandatory topics)', (tester) async {
357357
await prepare(tester, narrow: ChannelNarrow(channel.streamId),
358358
mandatoryTopics: true);
359359
checkComposeBoxHintTexts(tester,
360360
topicHintText: 'Topic',
361361
contentHintText: 'Message #${channel.name} > ${eg.defaultRealmEmptyTopicDisplayName}');
362-
}, skip: true); // null topic names soon to be enabled
362+
});
363363

364364
testWidgets('legacy: to ChannelNarrow with empty topic', (tester) async {
365365
await prepare(tester, narrow: ChannelNarrow(channel.streamId),
@@ -395,7 +395,7 @@ void main() {
395395
mandatoryTopics: false);
396396
checkComposeBoxHintTexts(tester, contentHintText:
397397
'Message #${channel.name} > ${eg.defaultRealmEmptyTopicDisplayName}');
398-
}, skip: true); // null topic names soon to be enabled
398+
});
399399

400400
testWidgets('to DmNarrow with self', (tester) async {
401401
await prepare(tester, narrow: DmNarrow.withUser(
@@ -714,7 +714,7 @@ void main() {
714714
..method.equals('POST')
715715
..url.path.equals('/api/v1/messages')
716716
..bodyFields['topic'].equals('');
717-
}, skip: true); // null topic names soon to be enabled
717+
});
718718

719719
testWidgets('legacy: empty topic -> "(no topic)"', (tester) async {
720720
await setupAndTapSend(tester,
@@ -739,7 +739,7 @@ void main() {
739739
topicInputText: eg.defaultRealmEmptyTopicDisplayName,
740740
mandatoryTopics: true);
741741
checkMessageNotSent(tester);
742-
}, skip: true); // null topic names soon to be enabled
742+
});
743743

744744
testWidgets('if topics are mandatory, reject "(no topic)"', (tester) async {
745745
await setupAndTapSend(tester,

test/widgets/inbox_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ void main() {
315315
unreadMessages: [eg.streamMessage(stream: channel, topic: '')]);
316316

317317
check(find.text(eg.defaultRealmEmptyTopicDisplayName)).findsOne();
318-
}, skip: true); // null topic names soon to be enabled
318+
});
319319

320320
group('topic visibility', () {
321321
final channel = eg.stream();

test/widgets/message_list_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ void main() {
817817
await tester.pump();
818818
check(findInMessageList('stream name')).length.equals(1);
819819
check(findInMessageList(eg.defaultRealmEmptyTopicDisplayName)).length.equals(1);
820-
}, skip: true); // null topic names soon to be enabled
820+
});
821821

822822
testWidgets('show general chat for empty topics without channel name', (tester) async {
823823
await setupMessageListPage(tester,
@@ -826,7 +826,7 @@ void main() {
826826
await tester.pump();
827827
check(findInMessageList('stream name')).length.equals(0);
828828
check(findInMessageList(eg.defaultRealmEmptyTopicDisplayName)).length.equals(1);
829-
}, skip: true); // null topic names soon to be enabled
829+
});
830830

831831
testWidgets('show topic visibility icon when followed', (tester) async {
832832
await setupMessageListPage(tester,

0 commit comments

Comments
 (0)