/
repeating_queries_list_controller.dart
76 lines (59 loc) · 2.22 KB
/
repeating_queries_list_controller.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import 'dart:math';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:list_controller/list_controller.dart';
class ListQuery extends Equatable {
const ListQuery({this.weightGt = 0});
final int weightGt;
@override
List<Object?> get props => [weightGt];
}
class LoadResult {
const LoadResult({required this.records, required this.isFinalPage});
final List<int> records;
final bool isFinalPage;
}
typedef ExListState = ListState<int, ListQuery>;
class RepeatingQueriesListController extends ValueNotifier<ExListState>
with ListCore<int>, RecordsLoader<int, ListQuery, LoadResult>, KeysetPagination<int, ListQuery, LoadResult> {
RepeatingQueriesListController() : super(const ListState(query: ListQuery())) {
loadRecords(const ListQuery());
}
bool _hadError = false; // to make sure we had at least one error
@override
void dispose() {
closeList();
super.dispose();
}
// RecordsLoader section:
@override
void onRecordsLoadStart({required ListQuery query, required LoadingKey loadingKey}) => value = value.copyWith(stage: ListStage.loading());
@override
Future<LoadResult> performLoadQuery({required ListQuery query, required LoadingKey loadingKey}) async {
await Future.delayed(const Duration(milliseconds: 1500));
if (Random().nextBool() || (query.weightGt > 40 && !_hadError)) {
_hadError = true;
if (!isListClosed) {
value = value.copyWith(stage: ListStage.error());
}
throw HandledLoadingException();
}
return LoadResult(
records: List<int>.generate(20, (i) => query.weightGt + i + 1),
isFinalPage: query.weightGt >= 80,
);
}
@override
void putLoadResultToState({required ListQuery query, required LoadResult loadResult, required LoadingKey loadingKey}) => value = value.copyWith(
records: [
...value.records,
...loadResult.records,
],
stage: loadResult.isFinalPage ? ListStage.complete() : ListStage.idle(),
);
// KeysetPagination section:
@override
ListStage getListStage(LoadingKey loadingKey) => value.stage;
@override
ListQuery buildNextPageQuery(LoadingKey loadingKey) => ListQuery(weightGt: value.records.last);
}