@@ -256,7 +256,7 @@ abstract class AutocompleteView<QueryT extends AutocompleteQuery, ResultT extend
256
256
}
257
257
}
258
258
259
- class MentionAutocompleteView extends AutocompleteView <MentionAutocompleteQuery , MentionAutocompleteResult , User > {
259
+ class MentionAutocompleteView extends AutocompleteView <MentionAutocompleteQuery , MentionAutocompleteResult , MentionableUser > {
260
260
MentionAutocompleteView ._({
261
261
required super .store,
262
262
required this .narrow,
@@ -277,13 +277,13 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
277
277
}
278
278
279
279
final Narrow narrow;
280
- final List <User > sortedUsers;
280
+ final List <MentionableUser > sortedUsers;
281
281
282
- static List <User > _usersByRelevance ({
282
+ static List <MentionableUser > _usersByRelevance ({
283
283
required PerAccountStore store,
284
284
required Narrow narrow,
285
285
}) {
286
- return store.users.values. toList ()
286
+ return [... store.users.values, ...store. wildcardsForNarrow (narrow).values]
287
287
..sort (_comparator (store: store, narrow: narrow));
288
288
}
289
289
@@ -303,7 +303,7 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
303
303
return _comparator (store: store, narrow: narrow)(userA, userB);
304
304
}
305
305
306
- static int Function (User , User ) _comparator ({
306
+ static int Function (MentionableUser , MentionableUser ) _comparator ({
307
307
required PerAccountStore store,
308
308
required Narrow narrow,
309
309
}) {
@@ -326,29 +326,36 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
326
326
store: store);
327
327
}
328
328
329
- static int _compareByRelevance (User userA, User userB, {
329
+ static int _compareByRelevance (MentionableUser userA, MentionableUser userB, {
330
330
required int ? streamId,
331
331
required String ? topic,
332
332
required PerAccountStore store,
333
333
}) {
334
- // TODO(#234): give preference to "all", "everyone" or "stream"
334
+ switch ((userA, userB)) {
335
+ case (Wildcard _, User _):
336
+ return - 1 ;
337
+ case (User _, Wildcard _):
338
+ return 1 ;
339
+ case (Wildcard wildcardA, Wildcard wildcardB):
340
+ return wildcardA.index.compareTo (wildcardB.index);
341
+ case (User userA, User userB):
342
+ // TODO(#618): give preference to subscribed users first
343
+
344
+ if (streamId != null ) {
345
+ final recencyResult = compareByRecency (userA, userB,
346
+ streamId: streamId,
347
+ topic: topic,
348
+ store: store);
349
+ if (recencyResult != 0 ) return recencyResult;
350
+ }
351
+ final dmsResult = compareByDms (userA, userB, store: store);
352
+ if (dmsResult != 0 ) return dmsResult;
335
353
336
- // TODO(#618): give preference to subscribed users first
354
+ final botStatusResult = compareByBotStatus (userA, userB);
355
+ if (botStatusResult != 0 ) return botStatusResult;
337
356
338
- if (streamId != null ) {
339
- final recencyResult = compareByRecency (userA, userB,
340
- streamId: streamId,
341
- topic: topic,
342
- store: store);
343
- if (recencyResult != 0 ) return recencyResult;
357
+ return compareByAlphabeticalOrder (userA, userB, store: store);
344
358
}
345
- final dmsResult = compareByDms (userA, userB, store: store);
346
- if (dmsResult != 0 ) return dmsResult;
347
-
348
- final botStatusResult = compareByBotStatus (userA, userB);
349
- if (botStatusResult != 0 ) return botStatusResult;
350
-
351
- return compareByAlphabeticalOrder (userA, userB, store: store);
352
359
}
353
360
354
361
/// Determines which of the two users has more recent activity (messages sent
@@ -385,19 +392,6 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
385
392
streamId: streamId, senderId: userB.userId));
386
393
}
387
394
388
- @override
389
- Iterable <User > getSortedItemsToTest (MentionAutocompleteQuery query) {
390
- return sortedUsers;
391
- }
392
-
393
- @override
394
- MentionAutocompleteResult ? testItem (MentionAutocompleteQuery query, User item) {
395
- if (query.testUser (item, store.autocompleteViewManager.autocompleteDataCache)) {
396
- return UserMentionAutocompleteResult (userId: item.userId);
397
- }
398
- return null ;
399
- }
400
-
401
395
/// Determines which of the two users is more recent in DM conversations.
402
396
///
403
397
/// Returns a negative number if [userA] is more recent than [userB] ,
@@ -450,6 +444,37 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
450
444
return userAName.compareTo (userBName); // TODO(i18n): add locale-aware sorting
451
445
}
452
446
447
+ @override
448
+ Iterable <MentionableUser > getSortedItemsToTest (MentionAutocompleteQuery query) {
449
+ return sortedUsers;
450
+ }
451
+
452
+ bool _isChannelWildcardIncluded = false ;
453
+
454
+ @override
455
+ MentionAutocompleteResult ? testItem (MentionAutocompleteQuery query, MentionableUser item) {
456
+ if (query.testUser (item, store.autocompleteViewManager.autocompleteDataCache)) {
457
+ switch (item) {
458
+ case User user:
459
+ return UserMentionAutocompleteResult (userId: user.userId);
460
+ case Wildcard wildcard:
461
+ final isChannelWildcard = wildcard.type == WildcardType .channel;
462
+ if (isChannelWildcard && _isChannelWildcardIncluded) break ;
463
+ if (isChannelWildcard) {
464
+ _isChannelWildcardIncluded = true ;
465
+ }
466
+ return WildcardMentionAutocompleteResult (wildcardName: wildcard.name);
467
+ }
468
+ }
469
+ return null ;
470
+ }
471
+
472
+ @override
473
+ Future <void > _startSearch (MentionAutocompleteQuery query) async {
474
+ _isChannelWildcardIncluded = false ;
475
+ return super ._startSearch (query);
476
+ }
477
+
453
478
@override
454
479
void dispose () {
455
480
store.autocompleteViewManager.unregisterMentionAutocomplete (this );
@@ -496,16 +521,15 @@ class MentionAutocompleteQuery extends AutocompleteQuery {
496
521
/// Whether the user wants a silent mention (@_query, vs. @query).
497
522
final bool silent;
498
523
499
- bool testUser (User user, AutocompleteDataCache cache) {
500
- // TODO(#236) test email too, not just name
501
-
502
- if (! user.isActive) return false ;
503
-
504
- return _testName (user, cache);
505
- }
506
-
507
- bool _testName (User user, AutocompleteDataCache cache) {
508
- return _testContainsQueryWords (cache.nameWordsForUser (user));
524
+ bool testUser (MentionableUser user, AutocompleteDataCache cache) {
525
+ switch (user) {
526
+ case User ():
527
+ if (! user.isActive) return false ;
528
+ // TODO(#236) test email too, not just name
529
+ return _testContainsQueryWords (cache.nameWordsForUser (user));
530
+ case Wildcard ():
531
+ return user.name.contains (raw.toLowerCase ());
532
+ }
509
533
}
510
534
511
535
@override
@@ -552,9 +576,13 @@ class UserMentionAutocompleteResult extends MentionAutocompleteResult {
552
576
final int userId;
553
577
}
554
578
555
- // TODO(#233): // class UserGroupMentionAutocompleteResult extends MentionAutocompleteResult {
579
+ class WildcardMentionAutocompleteResult extends MentionAutocompleteResult {
580
+ WildcardMentionAutocompleteResult ({required this .wildcardName});
581
+
582
+ final String wildcardName;
583
+ }
556
584
557
- // TODO(#234 ): // class WildcardMentionAutocompleteResult extends MentionAutocompleteResult {
585
+ // TODO(#233 ): // class UserGroupMentionAutocompleteResult extends MentionAutocompleteResult {
558
586
559
587
class TopicAutocompleteView extends AutocompleteView <TopicAutocompleteQuery , TopicAutocompleteResult , String > {
560
588
TopicAutocompleteView ._({required super .store, required this .streamId});
0 commit comments