Skip to content

Commit c25b2f5

Browse files
committed
do not merge; api: Make displayName nullable
Signed-off-by: Zixuan James Li <[email protected]>
1 parent ccd571d commit c25b2f5

13 files changed

+16
-31
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
@@ -942,15 +942,13 @@ class TopicAutocompleteQuery extends AutocompleteQuery {
942942
bool testTopic(PerAccountStore store, TopicName topic) {
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
// This checks for inequality because there is nothing to autocomplete to
951950
// when `raw` already matches the topic exactly.
952951
return topic.displayName != raw
953-
// ignore: unnecessary_non_null_assertion // null topic names soon to be enabled
954952
&& topic.displayName!.toLowerCase().contains(raw.toLowerCase());
955953
}
956954

lib/widgets/action_sheet.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ void showTopicActionSheet(BuildContext context, {
253253
// TODO: check for other cases that may disallow this action (e.g.: time
254254
// limit for editing topics).
255255
final allowResolveUnresolve =
256-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
257256
message == null || message.topic.displayName != null;
258257
if (someMessageIdInTopic != null && allowResolveUnresolve) {
259258
optionButtons.add(ResolveUnresolveButton(pageContext: pageContext,

lib/widgets/autocomplete.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,11 @@ class TopicAutocomplete extends AutocompleteField<TopicAutocompleteQuery, TopicA
366366
@override
367367
Widget buildItem(BuildContext context, int index, TopicAutocompleteResult option) {
368368
final Widget child;
369-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
370369
if (option.topic.displayName == null) {
371370
final store = PerAccountStoreWidget.of(context);
372371
child = Text(store.realmEmptyTopicDisplayName,
373372
style: const TextStyle(fontStyle: FontStyle.italic));
374373
} else {
375-
// ignore: unnecessary_non_null_assertion // null topic names soon to be enabled
376374
child = Text(option.topic.displayName!);
377375
}
378376

lib/widgets/compose_box.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ class ComposeTopicController extends ComposeController<TopicValidationError> {
201201
}
202202

203203
void setTopic(TopicName newTopic) {
204-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
205204
value = TextEditingValue(text: newTopic.displayName ?? '');
206205
}
207206
}
@@ -612,7 +611,6 @@ class _StreamContentInputState extends State<_StreamContentInput> {
612611
if (store.realmMandatoryTopics && widget.controller.topic.isTopicVacuous) {
613612
topicDisplayName = null;
614613
} else {
615-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
616614
topicDisplayName = topic.displayName ?? store.realmEmptyTopicDisplayName;
617615
}
618616

@@ -682,7 +680,6 @@ class _FixedDestinationContentInput extends StatelessWidget {
682680
final streamName = store.streams[streamId]?.name
683681
?? zulipLocalizations.unknownChannelName;
684682
return zulipLocalizations.composeBoxChannelTopicContentHint(
685-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
686683
'#$streamName > ${topic.displayName ?? store.realmEmptyTopicDisplayName}');
687684

688685
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
@@ -537,15 +537,13 @@ class _TopicItem extends StatelessWidget {
537537
child: Text(
538538
style: TextStyle(
539539
fontSize: 17,
540-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
541540
fontStyle: topic.displayName == null ? FontStyle.italic : null,
542541
height: (20 / 17),
543542
// TODO(design) check if this is the right variable
544543
color: designVariables.labelMenuButton,
545544
),
546545
maxLines: 2,
547546
overflow: TextOverflow.ellipsis,
548-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
549547
topic.displayName ?? store.realmEmptyTopicDisplayName))),
550548
const SizedBox(width: 12),
551549
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
@@ -366,10 +366,8 @@ class MessageListAppBarTitle extends StatelessWidget {
366366
return Row(
367367
mainAxisSize: MainAxisSize.min,
368368
children: [
369-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
370369
Flexible(child: Text(topic.displayName ?? store.realmEmptyTopicDisplayName, style: TextStyle(
371370
fontSize: 13,
372-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
373371
fontStyle: topic.displayName == null ? FontStyle.italic : null,
374372
).merge(weightVariableTextStyle(context)))),
375373
if (icon != null)
@@ -1120,13 +1118,11 @@ class StreamMessageRecipientHeader extends StatelessWidget {
11201118
child: Row(
11211119
children: [
11221120
Flexible(
1123-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
11241121
child: Text(topic.displayName ?? store.realmEmptyTopicDisplayName,
11251122
// TODO: Give a way to see the whole topic (maybe a
11261123
// long-press interaction?)
11271124
overflow: TextOverflow.ellipsis,
11281125
style: recipientHeaderTextStyle(context).copyWith(
1129-
// ignore: unnecessary_null_comparison // null topic names soon to be enabled
11301126
fontStyle: topic.displayName == null ? FontStyle.italic : null,
11311127
))),
11321128
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: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ void main() {
190190

191191
final topicRow = find.descendant(
192192
of: find.byType(ZulipAppBar),
193-
// ignore: dead_null_aware_expression // null topic names soon to be enabled
194193
matching: find.text(topicName.displayName ?? eg.defaultRealmEmptyTopicDisplayName));
195194
await tester.longPress(topicRow);
196195
// sheet appears onscreen; default duration of bottom-sheet enter animation
@@ -211,7 +210,7 @@ void main() {
211210

212211
await tester.longPress(find.descendant(
213212
of: find.byType(RecipientHeader),
214-
matching: find.text(effectiveMessage.topic.displayName)));
213+
matching: find.text(effectiveMessage.topic.displayName!)));
215214
// sheet appears onscreen; default duration of bottom-sheet enter animation
216215
await tester.pump(const Duration(milliseconds: 250));
217216
}
@@ -275,7 +274,7 @@ void main() {
275274
messages: [message]);
276275
check(findButtonForLabel('Mark as resolved')).findsNothing();
277276
check(findButtonForLabel('Mark as unresolved')).findsNothing();
278-
}, skip: true); // null topic names soon to be enabled
277+
});
279278

280279
testWidgets('show from recipient header', (tester) async {
281280
await prepare();

test/widgets/autocomplete_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ void main() {
355355
await tester.tap(find.text('Topic three'));
356356
await tester.pumpAndSettle();
357357
check(tester.widget<TextField>(topicInputFinder).controller!.text)
358-
.equals(topic3.name.displayName);
358+
.equals(topic3.name.displayName!);
359359
check(find.text('Topic one' )).findsNothing();
360360
check(find.text('Topic two' )).findsNothing();
361361
check(find.text('Topic three')).findsOne(); // shown in `_TopicInput` once
@@ -412,7 +412,7 @@ void main() {
412412
await tester.pumpAndSettle();
413413

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

417417
testWidgets('match general chat in autocomplete', (tester) async {
418418
final topic = eg.getStreamTopicsEntry(name: '');
@@ -424,7 +424,7 @@ void main() {
424424
await tester.pumpAndSettle();
425425

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

429429
testWidgets('autocomplete to general chat sets topic to empty string', (tester) async {
430430
final topic = eg.getStreamTopicsEntry(name: '');
@@ -439,6 +439,6 @@ void main() {
439439
await tester.tap(find.text(eg.defaultRealmEmptyTopicDisplayName));
440440
await tester.pump(Duration.zero);
441441
check(controller.value).text.equals('');
442-
}, skip: true); // null topic names soon to be enabled
442+
});
443443
});
444444
}

test/widgets/compose_box_test.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ void main() {
366366
checkComposeBoxHintTexts(tester,
367367
topicHintText: 'Topic',
368368
contentHintText: 'Message #${channel.name} > ${eg.defaultRealmEmptyTopicDisplayName}');
369-
}, skip: true); // null topic names soon to be enabled
369+
});
370370

371371
testWidgets('legacy: with empty topic', (tester) async {
372372
await prepare(tester, narrow: ChannelNarrow(channel.streamId),
@@ -396,7 +396,7 @@ void main() {
396396
checkComposeBoxHintTexts(tester,
397397
topicHintText: 'Topic',
398398
contentHintText: 'Message #${channel.name}');
399-
}, skip: true); // null topic names soon to be enabled
399+
});
400400

401401
testWidgets('legacy: with empty topic', (tester) async {
402402
await prepare(tester, narrow: ChannelNarrow(channel.streamId),
@@ -433,7 +433,7 @@ void main() {
433433
mandatoryTopics: false);
434434
checkComposeBoxHintTexts(tester, contentHintText:
435435
'Message #${channel.name} > ${eg.defaultRealmEmptyTopicDisplayName}');
436-
}, skip: true); // null topic names soon to be enabled
436+
});
437437

438438
testWidgets('to DmNarrow with self', (tester) async {
439439
await prepare(tester, narrow: DmNarrow.withUser(
@@ -749,7 +749,7 @@ void main() {
749749
..method.equals('POST')
750750
..url.path.equals('/api/v1/messages')
751751
..bodyFields['topic'].equals('');
752-
}, skip: true); // null topic names soon to be enabled
752+
});
753753

754754
testWidgets('legacy: empty topic -> "(no topic)"', (tester) async {
755755
await setupAndTapSend(tester,
@@ -774,7 +774,7 @@ void main() {
774774
topicInputText: eg.defaultRealmEmptyTopicDisplayName,
775775
mandatoryTopics: true);
776776
checkMessageNotSent(tester);
777-
}, skip: true); // null topic names soon to be enabled
777+
});
778778

779779
testWidgets('if topics are mandatory, reject "(no topic)"', (tester) async {
780780
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
@@ -862,7 +862,7 @@ void main() {
862862
await tester.pump();
863863
check(findInMessageList('stream name')).single;
864864
check(findInMessageList(eg.defaultRealmEmptyTopicDisplayName)).single;
865-
}, skip: true); // null topic names soon to be enabled
865+
});
866866

867867
testWidgets('show general chat for empty topics without channel name', (tester) async {
868868
await setupMessageListPage(tester,
@@ -871,7 +871,7 @@ void main() {
871871
await tester.pump();
872872
check(findInMessageList('stream name')).isEmpty();
873873
check(findInMessageList(eg.defaultRealmEmptyTopicDisplayName)).single;
874-
}, skip: true); // null topic names soon to be enabled
874+
});
875875

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

0 commit comments

Comments
 (0)