Skip to content

Commit b0d2b76

Browse files
committed
autocomplete [nfc]: Add silent to MentionAutocompleteQuery
As it does in the web app, we'll want this bit to control the suggestion filtering: if the user wants a silent mention, then it won't make sense to offer wildcard mentions in the list (@ALL, @everyone, etc.).
1 parent 5ee7729 commit b0d2b76

File tree

2 files changed

+44
-40
lines changed

2 files changed

+44
-40
lines changed

lib/model/autocomplete.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ extension Autocomplete on ContentTextEditingController {
3636
}
3737
return AutocompleteIntent(
3838
syntaxStart: position,
39-
query: MentionAutocompleteQuery(match[1]!),
39+
query: MentionAutocompleteQuery(match[2]!, silent: match[1]! == '_'),
4040
textEditingValue: value);
4141
}
4242
return null;
@@ -58,7 +58,7 @@ final RegExp mentionAutocompleteMarkerRegex = (() {
5858

5959
return RegExp(
6060
beforeAtSign
61-
+ r'@_?'
61+
+ r'@(_?)' // capture, so we can distinguish silent mentions
6262
+ r'(|'
6363
// Reject on whitespace right after "@" or "@_". Emails can't start with
6464
// it, and full_name can't either (it's run through Python's `.strip()`).
@@ -272,11 +272,14 @@ class MentionAutocompleteView extends ChangeNotifier {
272272
}
273273

274274
class MentionAutocompleteQuery {
275-
MentionAutocompleteQuery(this.raw)
275+
MentionAutocompleteQuery(this.raw, {this.silent = false})
276276
: _lowercaseWords = raw.toLowerCase().split(' ');
277277

278278
final String raw;
279279

280+
/// Whether the user wants a silent mention (@_query, vs. @query).
281+
final bool silent;
282+
280283
final List<String> _lowercaseWords;
281284

282285
bool testUser(User user, AutocompleteDataCache cache) {
@@ -304,16 +307,16 @@ class MentionAutocompleteQuery {
304307

305308
@override
306309
String toString() {
307-
return '${objectRuntimeType(this, 'MentionAutocompleteQuery')}(raw: $raw})';
310+
return '${objectRuntimeType(this, 'MentionAutocompleteQuery')}(raw: $raw, silent: $silent})';
308311
}
309312

310313
@override
311314
bool operator ==(Object other) {
312-
return other is MentionAutocompleteQuery && other.raw == raw;
315+
return other is MentionAutocompleteQuery && other.raw == raw && other.silent == silent;
313316
}
314317

315318
@override
316-
int get hashCode => Object.hash('MentionAutocompleteQuery', raw);
319+
int get hashCode => Object.hash('MentionAutocompleteQuery', raw, silent);
317320
}
318321

319322
class AutocompleteDataCache {

test/model/autocomplete_test.dart

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ void main() {
8181
});
8282
}
8383

84-
MentionAutocompleteQuery queryOf(String raw) => MentionAutocompleteQuery(raw);
84+
MentionAutocompleteQuery queryOf(String raw) => MentionAutocompleteQuery(raw, silent: false);
85+
MentionAutocompleteQuery silentQueryOf(String raw) => MentionAutocompleteQuery(raw, silent: true);
8586

8687
doTest('', null);
8788
doTest('^', null);
@@ -120,46 +121,46 @@ void main() {
120121

121122
doTest('~@^_', queryOf('')); // Odd/unlikely, but should not crash
122123

123-
doTest('~@__^', queryOf('_'));
124+
doTest('~@__^', silentQueryOf('_'));
124125

125-
doTest('~@^abc^', queryOf('abc')); doTest('~@_^abc^', queryOf('abc'));
126-
doTest('~@a^bc^', queryOf('abc')); doTest('~@_a^bc^', queryOf('abc'));
127-
doTest('~@ab^c^', queryOf('abc')); doTest('~@_ab^c^', queryOf('abc'));
128-
doTest('~^@^', queryOf('')); doTest('~^@_^', queryOf(''));
126+
doTest('~@^abc^', queryOf('abc')); doTest('~@_^abc^', silentQueryOf('abc'));
127+
doTest('~@a^bc^', queryOf('abc')); doTest('~@_a^bc^', silentQueryOf('abc'));
128+
doTest('~@ab^c^', queryOf('abc')); doTest('~@_ab^c^', silentQueryOf('abc'));
129+
doTest('~^@^', queryOf('')); doTest('~^@_^', silentQueryOf(''));
129130
// but:
130131
doTest('^hello @chris^', null); doTest('^hello @_chris^', null);
131132

132-
doTest('~@[email protected]^', queryOf('[email protected]')); doTest('~@[email protected]^', queryOf('[email protected]'));
133-
doTest('~@me@^zulip.com^', queryOf('[email protected]')); doTest('~@_me@^zulip.com^', queryOf('[email protected]'));
134-
doTest('~@me^@zulip.com^', queryOf('[email protected]')); doTest('~@_me^@zulip.com^', queryOf('[email protected]'));
135-
doTest('~@^[email protected]^', queryOf('[email protected]')); doTest('~@_^[email protected]^', queryOf('[email protected]'));
136-
137-
doTest('~@abc^', queryOf('abc')); doTest('~@_abc^', queryOf('abc'));
138-
doTest(' ~@abc^', queryOf('abc')); doTest(' ~@_abc^', queryOf('abc'));
139-
doTest('(~@abc^', queryOf('abc')); doTest('(~@_abc^', queryOf('abc'));
140-
doTest('—~@abc^', queryOf('abc')); doTest('—~@_abc^', queryOf('abc'));
141-
doTest('"~@abc^', queryOf('abc')); doTest('"~@_abc^', queryOf('abc'));
142-
doTest('“~@abc^', queryOf('abc')); doTest('“~@_abc^', queryOf('abc'));
143-
doTest('。~@abc^', queryOf('abc')); doTest('。~@_abc^', queryOf('abc'));
144-
doTest('«~@abc^', queryOf('abc')); doTest('«~@_abc^', queryOf('abc'));
145-
146-
doTest('~@ab^c', queryOf('ab')); doTest('~@_ab^c', queryOf('ab'));
147-
doTest('~@a^bc', queryOf('a')); doTest('~@_a^bc', queryOf('a'));
148-
doTest('~@^abc', queryOf('')); doTest('~@_^abc', queryOf(''));
149-
doTest('~@^', queryOf('')); doTest('~@_^', queryOf(''));
150-
151-
doTest('~@abc ^', queryOf('abc ')); doTest('~@_abc ^', queryOf('abc '));
152-
doTest('~@abc^ ^', queryOf('abc ')); doTest('~@_abc^ ^', queryOf('abc '));
153-
doTest('~@ab^c ^', queryOf('abc ')); doTest('~@_ab^c ^', queryOf('abc '));
154-
doTest('~@^abc ^', queryOf('abc ')); doTest('~@_^abc ^', queryOf('abc '));
155-
156-
doTest('Please ask ~@chris^', queryOf('chris')); doTest('Please ask ~@_chris^', queryOf('chris'));
157-
doTest('Please ask ~@chris bobbe^', queryOf('chris bobbe')); doTest('Please ask ~@_chris bobbe^', queryOf('chris bobbe'));
133+
doTest('~@[email protected]^', queryOf('[email protected]')); doTest('~@[email protected]^', silentQueryOf('[email protected]'));
134+
doTest('~@me@^zulip.com^', queryOf('[email protected]')); doTest('~@_me@^zulip.com^', silentQueryOf('[email protected]'));
135+
doTest('~@me^@zulip.com^', queryOf('[email protected]')); doTest('~@_me^@zulip.com^', silentQueryOf('[email protected]'));
136+
doTest('~@^[email protected]^', queryOf('[email protected]')); doTest('~@_^[email protected]^', silentQueryOf('[email protected]'));
137+
138+
doTest('~@abc^', queryOf('abc')); doTest('~@_abc^', silentQueryOf('abc'));
139+
doTest(' ~@abc^', queryOf('abc')); doTest(' ~@_abc^', silentQueryOf('abc'));
140+
doTest('(~@abc^', queryOf('abc')); doTest('(~@_abc^', silentQueryOf('abc'));
141+
doTest('—~@abc^', queryOf('abc')); doTest('—~@_abc^', silentQueryOf('abc'));
142+
doTest('"~@abc^', queryOf('abc')); doTest('"~@_abc^', silentQueryOf('abc'));
143+
doTest('“~@abc^', queryOf('abc')); doTest('“~@_abc^', silentQueryOf('abc'));
144+
doTest('。~@abc^', queryOf('abc')); doTest('。~@_abc^', silentQueryOf('abc'));
145+
doTest('«~@abc^', queryOf('abc')); doTest('«~@_abc^', silentQueryOf('abc'));
146+
147+
doTest('~@ab^c', queryOf('ab')); doTest('~@_ab^c', silentQueryOf('ab'));
148+
doTest('~@a^bc', queryOf('a')); doTest('~@_a^bc', silentQueryOf('a'));
149+
doTest('~@^abc', queryOf('')); doTest('~@_^abc', silentQueryOf(''));
150+
doTest('~@^', queryOf('')); doTest('~@_^', silentQueryOf(''));
151+
152+
doTest('~@abc ^', queryOf('abc ')); doTest('~@_abc ^', silentQueryOf('abc '));
153+
doTest('~@abc^ ^', queryOf('abc ')); doTest('~@_abc^ ^', silentQueryOf('abc '));
154+
doTest('~@ab^c ^', queryOf('abc ')); doTest('~@_ab^c ^', silentQueryOf('abc '));
155+
doTest('~@^abc ^', queryOf('abc ')); doTest('~@_^abc ^', silentQueryOf('abc '));
156+
157+
doTest('Please ask ~@chris^', queryOf('chris')); doTest('Please ask ~@_chris^', silentQueryOf('chris'));
158+
doTest('Please ask ~@chris bobbe^', queryOf('chris bobbe')); doTest('Please ask ~@_chris bobbe^', silentQueryOf('chris bobbe'));
158159

159160
doTest('~@Rodion Romanovich Raskolnikov^', queryOf('Rodion Romanovich Raskolnikov'));
160-
doTest('~@_Rodion Romanovich Raskolniko^', queryOf('Rodion Romanovich Raskolniko'));
161+
doTest('~@_Rodion Romanovich Raskolniko^', silentQueryOf('Rodion Romanovich Raskolniko'));
161162
doTest('~@Родион Романович Раскольников^', queryOf('Родион Романович Раскольников'));
162-
doTest('~@_Родион Романович Раскольнико^', queryOf('Родион Романович Раскольнико'));
163+
doTest('~@_Родион Романович Раскольнико^', silentQueryOf('Родион Романович Раскольнико'));
163164
doTest('If @chris is around, please ask him.^', null); // @ sign is too far away from cursor
164165
doTest('If @_chris is around, please ask him.^', null); // @ sign is too far away from cursor
165166
});

0 commit comments

Comments
 (0)