Skip to content

Commit d8c373a

Browse files
committed
autocomplete [nfc]: Factor out AutocompleteDataProvider
`AutocompleteDataProvider` provides the full list of possible items and filter predicate for `AutocompleteView` without having to deal with state management or result computation process. With this factored out of `AutocompleteView` it's responsibility is limited to only managing the autocomplete state. While fetching data and setting the logic on passing items to query filter is the responsibility of `AutocompleteDataProvider`.
1 parent d0344b9 commit d8c373a

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

lib/model/autocomplete.dart

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,20 @@ class AutocompleteViewManager {
151151
// void dispose() { … }
152152
}
153153

154+
/// Provides the full list of possible items and filter predicate for
155+
/// `AutocompleteView` without having to deal with state management or
156+
/// result computation process.
157+
///
158+
/// Having this factored out of `AutocompleteView` helps in limiting
159+
/// it's responsibility to managing the autocomplete state and result
160+
/// computation process.
161+
abstract class AutocompleteDataProvider<T, Q extends AutocompleteQuery, R extends AutocompleteResult> {
162+
163+
Iterable<T> getDataForQuery(Q query);
164+
165+
R? testItem(Q query, T item);
166+
}
167+
154168
/// A view-model for an autocomplete interaction.
155169
///
156170
/// The owner of one of these objects must call [dispose] when the object
@@ -164,17 +178,14 @@ class AutocompleteViewManager {
164178
/// * When the object will no longer be used, call [dispose] to free
165179
/// resources on the [PerAccountStore].
166180
abstract class AutocompleteView<Q extends AutocompleteQuery, R extends AutocompleteResult> extends ChangeNotifier {
181+
final AutocompleteDataProvider<Object, Q, R> dataProvider;
167182

168183
/// This could be used to transform results after they've been
169184
/// computed for sorting, filtering etc.
170185
final List<R> Function(List<R> results)? resultsFilter;
171186
final PerAccountStore store;
172187

173-
AutocompleteView({this.resultsFilter, required this.store});
174-
175-
Iterable<Object> getDataForQuery(Q query);
176-
177-
R? testItem(Q query, Object item);
188+
AutocompleteView({required this.dataProvider, this.resultsFilter, required this.store});
178189

179190
Q? get query => _query;
180191
Q? _query;
@@ -221,7 +232,7 @@ abstract class AutocompleteView<Q extends AutocompleteQuery, R extends Autocompl
221232

222233
Future<List<R>?> _computeResults(Q query) async {
223234
final List<R> results = [];
224-
final Iterable<Object> data = getDataForQuery(query);
235+
final Iterable<Object> data = dataProvider.getDataForQuery(query);
225236

226237
final iterator = data.iterator;
227238
bool isDone = false;
@@ -238,26 +249,23 @@ abstract class AutocompleteView<Q extends AutocompleteQuery, R extends Autocompl
238249
isDone = true;
239250
break;
240251
}
241-
final Object item = iterator.current;
242-
final result = testItem(query, item);
252+
final result = dataProvider.testItem(query, iterator.current);
243253
if (result != null) results.add(result);
244254
}
245255
}
246256
return resultsFilter?.call(results) ?? results;
247257
}
248258
}
249259

250-
class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery, MentionAutocompleteResult> {
260+
class MentionAutocompleteDataProvider extends AutocompleteDataProvider<Object, MentionAutocompleteQuery, MentionAutocompleteResult> {
251261
final Narrow narrow;
262+
final PerAccountStore store;
252263
final List<User> sortedUsers;
253264

254-
MentionAutocompleteView.init({
255-
required super.store,
256-
required this.narrow,
257-
}) : sortedUsers = _usersByRelevance(store: store, narrow: narrow)
258-
{
259-
store.autocompleteViewManager.registerMentionAutocomplete(this);
260-
}
265+
MentionAutocompleteDataProvider({
266+
required this.store,
267+
required this.narrow
268+
}) : sortedUsers = _usersByRelevance(store: store, narrow: narrow);
261269

262270
static List<User> _usersByRelevance({
263271
required PerAccountStore store,
@@ -302,6 +310,18 @@ class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery,
302310
_ => 0,
303311
};
304312
}
313+
}
314+
315+
class MentionAutocompleteView extends AutocompleteView<MentionAutocompleteQuery, MentionAutocompleteResult> {
316+
317+
MentionAutocompleteView.init({
318+
required super.store,
319+
required Narrow narrow,
320+
}) : super(dataProvider: MentionAutocompleteDataProvider(
321+
store: store,
322+
narrow: narrow)) {
323+
store.autocompleteViewManager.registerMentionAutocomplete(this);
324+
}
305325

306326
@override
307327
void dispose() {

test/model/autocomplete_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ void main() {
368368
const idA = 1;
369369
const idB = 2;
370370

371-
int compareAB() => MentionAutocompleteView.compareByDms(
371+
int compareAB() => MentionAutocompleteDataProvider.compareByDms(
372372
eg.user(userId: idA),
373373
eg.user(userId: idB),
374374
store: store,

0 commit comments

Comments
 (0)