Skip to content

Commit 4fbe8ee

Browse files
sm-sayedignprice
andcommitted
autocomplete: Introduce a field for sorted users
This field will be used to maintain a list of sorted users based on the most relevant autocomplete criteria in the upcoming commits. Co-authored-by: Greg Price <[email protected]>
1 parent 2272e77 commit 4fbe8ee

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

lib/model/autocomplete.dart

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ class MentionAutocompleteView extends ChangeNotifier {
178178
@override
179179
void dispose() {
180180
store.autocompleteViewManager.unregisterMentionAutocomplete(this);
181+
_sortedUsers = null;
181182
// We cancel in-progress computations by checking [hasListeners] between tasks.
182183
// After [super.dispose] is called, [hasListeners] returns false.
183184
// TODO test that logic (may involve detecting an unhandled Future rejection; how?)
@@ -201,6 +202,7 @@ class MentionAutocompleteView extends ChangeNotifier {
201202
/// This will redo the search from scratch for the current query, if any.
202203
void reassemble() {
203204
if (_query != null) {
205+
_sortedUsers = null;
204206
_startSearch(_query!);
205207
}
206208
}
@@ -230,22 +232,43 @@ class MentionAutocompleteView extends ChangeNotifier {
230232
notifyListeners();
231233
}
232234

235+
List<User>? _sortedUsers;
236+
237+
List<User> sortByRelevance({required List<User> users}) {
238+
return users; // TODO(#228) sort for most relevant first
239+
}
240+
241+
void _sortUsers() {
242+
final users = store.users.values.toList();
243+
_sortedUsers = sortByRelevance(users: users);
244+
}
245+
233246
Future<List<MentionAutocompleteResult>?> _computeResults(MentionAutocompleteQuery query) async {
234247
final List<MentionAutocompleteResult> results = [];
235-
final Iterable<User> users = store.users.values;
236248

237-
final iterator = users.iterator;
249+
if (_sortedUsers == null) {
250+
_sortUsers();
251+
}
252+
253+
final sortedUsers = _sortedUsers!;
254+
final iterator = sortedUsers.iterator;
238255
bool isDone = false;
239256
while (!isDone) {
240257
// CPU perf: End this task; enqueue a new one for resuming this work
241258
await Future(() {});
242259

260+
if (_sortedUsers != sortedUsers) {
261+
// The list of users this loop has been working from has become stale.
262+
// Abort so _startSearch can retry with the new list.
263+
throw ConcurrentModificationError();
264+
}
265+
243266
if (query != _query || !hasListeners) { // false if [dispose] has been called.
244267
return null;
245268
}
246269

247270
for (int i = 0; i < 1000; i++) {
248-
if (!iterator.moveNext()) { // Can throw ConcurrentModificationError
271+
if (!iterator.moveNext()) {
249272
isDone = true;
250273
break;
251274
}
@@ -256,7 +279,7 @@ class MentionAutocompleteView extends ChangeNotifier {
256279
}
257280
}
258281
}
259-
return results; // TODO(#228) sort for most relevant first
282+
return results;
260283
}
261284
}
262285

lib/model/store.dart

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -447,16 +447,6 @@ class PerAccountStore extends ChangeNotifier with StreamStore {
447447
user.profileData = null;
448448
}
449449
}
450-
// The following two lines will eventually not change [users], but are here to
451-
// trigger a modification to the collection as only changing the properties
452-
// of [user] does not signal a modification of [users] where needed.
453-
//
454-
// One example of this is [MentionAutocompleteView._computeResults] which
455-
// throws a `ConcurrentModificationError` when there is a modification done
456-
// to [users].
457-
users[-1] = user;
458-
users.remove(-1);
459-
460450
autocompleteViewManager.handleRealmUserUpdateEvent(event);
461451
notifyListeners();
462452
} else if (event is StreamEvent) {

0 commit comments

Comments
 (0)