Skip to content

Commit 33775e0

Browse files
committed
api: Make displayName nullable
Signed-off-by: Zixuan James Li <[email protected]>
1 parent 48b8bfb commit 33775e0

13 files changed

+18
-34
lines changed

lib/api/model/model.dart

+1-1
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

-2
Original file line numberDiff line numberDiff line change
@@ -942,13 +942,11 @@ class TopicAutocompleteQuery extends AutocompleteQuery {
942942
bool testTopic(TopicName topic, PerAccountStore store) {
943943
// TODO(#881): Sort by match relevance, like web does.
944944

945-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
946945
if (topic.displayName == null) {
947946
return store.realmEmptyTopicDisplayName.toLowerCase()
948947
.contains(raw.toLowerCase());
949948
}
950949
return topic.displayName != raw
951-
// ignore: unnecessary_non_null_assertion // null topic names soon to be enabled
952950
&& topic.displayName!.toLowerCase().contains(raw.toLowerCase());
953951
}
954952

lib/widgets/action_sheet.dart

+1-3
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,7 @@ void showTopicActionSheet(BuildContext context, {
302302

303303
// TODO: check for other cases that may disallow this action (e.g.: time
304304
// limit for editing topics).
305-
if (someMessageIdInTopic != null
306-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
307-
&& topic.displayName != null) {
305+
if (someMessageIdInTopic != null && topic.displayName != null) {
308306
optionButtons.add(ResolveUnresolveButton(pageContext: pageContext,
309307
topic: topic,
310308
someMessageIdInTopic: someMessageIdInTopic));

lib/widgets/autocomplete.dart

-2
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,11 @@ class TopicAutocomplete extends AutocompleteField<TopicAutocompleteQuery, TopicA
416416
@override
417417
Widget buildItem(BuildContext context, int index, TopicAutocompleteResult option) {
418418
final Widget child;
419-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
420419
if (option.topic.displayName == null) {
421420
final store = PerAccountStoreWidget.of(context);
422421
child = Text(store.realmEmptyTopicDisplayName,
423422
style: const TextStyle(fontStyle: FontStyle.italic));
424423
} else {
425-
// ignore: unnecessary_non_null_assertion // null topic names soon to be enabled
426424
child = Text(option.topic.displayName!);
427425
}
428426

lib/widgets/compose_box.dart

-3
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ class ComposeTopicController extends ComposeController<TopicValidationError> {
200200
}
201201

202202
void setTopic(TopicName newTopic) {
203-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
204203
value = TextEditingValue(text: newTopic.displayName ?? '');
205204
}
206205
}
@@ -657,7 +656,6 @@ class _StreamContentInputState extends State<_StreamContentInput> {
657656
// so don't make sense to translate. See:
658657
// https://github.com/zulip/zulip-flutter/pull/1148#discussion_r1941990585
659658
? '#$streamName'
660-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
661659
: '#$streamName > ${hintTopic.displayName ?? store.realmEmptyTopicDisplayName}';
662660

663661
return _ContentInput(
@@ -808,7 +806,6 @@ class _FixedDestinationContentInput extends StatelessWidget {
808806
// Zulip expresses channels and topics, not any normal English punctuation,
809807
// so don't make sense to translate. See:
810808
// https://github.com/zulip/zulip-flutter/pull/1148#discussion_r1941990585
811-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
812809
'#$streamName > ${topic.displayName ?? store.realmEmptyTopicDisplayName}');
813810

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

lib/widgets/inbox.dart

-2
Original file line numberDiff line numberDiff line change
@@ -546,14 +546,12 @@ class _TopicItem extends StatelessWidget {
546546
style: TextStyle(
547547
fontSize: 17,
548548
height: (20 / 17),
549-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
550549
fontStyle: topic.displayName == null ? FontStyle.italic : null,
551550
// TODO(design) check if this is the right variable
552551
color: designVariables.labelMenuButton,
553552
),
554553
maxLines: 2,
555554
overflow: TextOverflow.ellipsis,
556-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
557555
topic.displayName ?? store.realmEmptyTopicDisplayName))),
558556
const SizedBox(width: 12),
559557
if (hasMention) const _IconMarker(icon: ZulipIcons.at_sign),

lib/widgets/message_list.dart

-4
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,8 @@ class MessageListAppBarTitle extends StatelessWidget {
339339
return Row(
340340
mainAxisSize: MainAxisSize.min,
341341
children: [
342-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
343342
Flexible(child: Text(topic.displayName ?? store.realmEmptyTopicDisplayName, style: TextStyle(
344343
fontSize: 13,
345-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
346344
fontStyle: topic.displayName == null ? FontStyle.italic : null,
347345
).merge(weightVariableTextStyle(context)))),
348346
if (icon != null)
@@ -1114,13 +1112,11 @@ class StreamMessageRecipientHeader extends StatelessWidget {
11141112
child: Row(
11151113
children: [
11161114
Flexible(
1117-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
11181115
child: Text(topic.displayName ?? store.realmEmptyTopicDisplayName,
11191116
// TODO: Give a way to see the whole topic (maybe a
11201117
// long-press interaction?)
11211118
overflow: TextOverflow.ellipsis,
11221119
style: recipientHeaderTextStyle(context,
1123-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
11241120
fontStyle: topic.displayName == null ? FontStyle.italic : null,
11251121
))),
11261122
const SizedBox(width: 4),

test/api/model/model_checks.dart

+1-1
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

+2-3
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,6 @@ void main() {
372372
final topicRow = find.descendant(
373373
of: find.byType(ZulipAppBar),
374374
matching: find.text(
375-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
376375
effectiveTopic.displayName ?? eg.defaultRealmEmptyTopicDisplayName));
377376
await tester.longPress(topicRow);
378377
// sheet appears onscreen; default duration of bottom-sheet enter animation
@@ -393,7 +392,7 @@ void main() {
393392

394393
await tester.longPress(find.descendant(
395394
of: find.byType(RecipientHeader),
396-
matching: find.text(effectiveMessage.topic.displayName)));
395+
matching: find.text(effectiveMessage.topic.displayName!)));
397396
// sheet appears onscreen; default duration of bottom-sheet enter animation
398397
await tester.pump(const Duration(milliseconds: 250));
399398
}
@@ -457,7 +456,7 @@ void main() {
457456
messages: [message]);
458457
check(findButtonForLabel('Mark as resolved')).findsNothing();
459458
check(findButtonForLabel('Mark as unresolved')).findsNothing();
460-
}, skip: true); // null topic names soon to be enabled
459+
});
461460

462461
testWidgets('show from recipient header', (tester) async {
463462
await prepare();

test/widgets/autocomplete_test.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ void main() {
415415
await tester.tap(find.text('Topic three'));
416416
await tester.pumpAndSettle();
417417
check(tester.widget<TextField>(topicInputFinder).controller!.text)
418-
.equals(topic3.name.displayName);
418+
.equals(topic3.name.displayName!);
419419
check(find.text('Topic one' )).findsNothing();
420420
check(find.text('Topic two' )).findsNothing();
421421
check(find.text('Topic three')).findsOne(); // shown in `_TopicInput` once
@@ -473,7 +473,7 @@ void main() {
473473
await tester.pumpAndSettle();
474474

475475
check(find.text('some display name')).findsOne();
476-
}, skip: true); // null topic names soon to be enabled
476+
});
477477

478478
testWidgets('match realmEmptyTopicDisplayName in autocomplete', (tester) async {
479479
final topic = eg.getStreamTopicsEntry(name: '');
@@ -486,7 +486,7 @@ void main() {
486486
await tester.pumpAndSettle();
487487

488488
check(find.text('general chat')).findsOne();
489-
}, skip: true); // null topic names soon to be enabled
489+
});
490490

491491
testWidgets('autocomplete to realmEmptyTopicDisplayName sets topic to empty string', (tester) async {
492492
final topic = eg.getStreamTopicsEntry(name: '');
@@ -502,6 +502,6 @@ void main() {
502502
await tester.tap(find.text('general chat'));
503503
await tester.pump(Duration.zero);
504504
check(controller.value).text.equals('');
505-
}, skip: true); // null topic names soon to be enabled
505+
});
506506
});
507507
}

test/widgets/compose_box_test.dart

+5-5
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ void main() {
407407
topicHintText: eg.defaultRealmEmptyTopicDisplayName,
408408
contentHintText: 'Message #${channel.name} > '
409409
'${eg.defaultRealmEmptyTopicDisplayName}');
410-
}, skip: true); // null topic names soon to be enabled
410+
});
411411

412412
testWidgets('with empty topic, topic input has focus, then loses it', (tester) async {
413413
await prepare(tester, narrow: narrow, mandatoryTopics: false);
@@ -435,7 +435,7 @@ void main() {
435435
'${eg.defaultRealmEmptyTopicDisplayName}');
436436
check(tester.widget<TextField>(topicInputFinder)).decoration.isNotNull()
437437
.hintStyle.isNotNull().fontStyle.equals(FontStyle.italic);
438-
}, skip: true); // null topic names soon to be enabled
438+
});
439439

440440
testWidgets('legacy: with empty topic, content input has focus', (tester) async {
441441
await prepare(tester, narrow: narrow, mandatoryTopics: false,
@@ -464,7 +464,7 @@ void main() {
464464
topicHintText: 'Enter a topic '
465465
'(skip for “${eg.defaultRealmEmptyTopicDisplayName}”)',
466466
contentHintText: 'Message #${channel.name}');
467-
}, skip: true); // null topic names soon to be enabled
467+
});
468468

469469
testWidgets('with empty topic, content input has focus, then loses it', (tester) async {
470470
await prepare(tester, narrow: narrow, mandatoryTopics: false);
@@ -481,7 +481,7 @@ void main() {
481481
topicHintText: eg.defaultRealmEmptyTopicDisplayName,
482482
contentHintText: 'Message #${channel.name} > '
483483
'${eg.defaultRealmEmptyTopicDisplayName}');
484-
}, skip: true); // null topic names soon to be enabled
484+
});
485485

486486
testWidgets('with non-empty topic', (tester) async {
487487
await prepare(tester, narrow: narrow, mandatoryTopics: false);
@@ -557,7 +557,7 @@ void main() {
557557
narrow: TopicNarrow(channel.streamId, TopicName('')));
558558
checkComposeBoxHintTexts(tester, contentHintText:
559559
'Message #${channel.name} > ${eg.defaultRealmEmptyTopicDisplayName}');
560-
}, skip: true); // null topic names soon to be enabled
560+
});
561561
});
562562

563563
testWidgets('to DmNarrow with self', (tester) async {

test/widgets/inbox_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ void main() {
314314
subscriptions: [(eg.subscription(channel))],
315315
unreadMessages: [eg.streamMessage(stream: channel, topic: '')]);
316316
check(find.text(eg.defaultRealmEmptyTopicDisplayName)).findsOne();
317-
}, skip: true); // null topic names soon to be enabled
317+
});
318318

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

test/widgets/message_list_test.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ void main() {
202202
messageCount: 1);
203203
checkAppBarChannelTopic(
204204
channel.name, eg.defaultRealmEmptyTopicDisplayName);
205-
}, skip: true); // null topic names soon to be enabled
205+
});
206206

207207
testWidgets('has channel-feed action for topic narrows', (tester) async {
208208
final pushedRoutes = <Route<void>>[];
@@ -953,7 +953,7 @@ void main() {
953953
await tester.pump();
954954
check(findInMessageList('stream name')).single;
955955
check(findInMessageList(eg.defaultRealmEmptyTopicDisplayName)).single;
956-
}, skip: true); // null topic names soon to be enabled
956+
});
957957

958958
testWidgets('show general chat for empty topics without channel name', (tester) async {
959959
await setupMessageListPage(tester,
@@ -962,7 +962,7 @@ void main() {
962962
await tester.pump();
963963
check(findInMessageList('stream name')).isEmpty();
964964
check(findInMessageList(eg.defaultRealmEmptyTopicDisplayName)).single;
965-
}, skip: true); // null topic names soon to be enabled
965+
});
966966

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

0 commit comments

Comments
 (0)