Skip to content

Commit 302df0f

Browse files
committed
Revert "Revert "Added a callback so that the RefreshIndicator won't stop early""
This reverts commit 3cc01f64 because apparently this is the correct way to do it, as sneaky as it seems. See brianegan/flutter_redux#6 (comment)
1 parent 9c8ca03 commit 302df0f

File tree

6 files changed

+69
-44
lines changed

6 files changed

+69
-44
lines changed

lib/actions/actions.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
library actions;
22

3+
import 'dart:async';
4+
35
import 'package:betterstatmobile/models/models.dart';
46
import 'package:built_redux/built_redux.dart';
57
import 'package:built_value/built_value.dart';
@@ -10,7 +12,7 @@ part 'actions.g.dart';
1012
abstract class AppActions implements ReduxActions {
1113
ActionDispatcher<Schedule> addScheduleAction;
1214
ActionDispatcher<String> deleteScheduleAction;
13-
ActionDispatcher<Null> fetchSchedulesAction;
15+
ActionDispatcher<Completer<Null>> fetchSchedulesAction;
1416
ActionDispatcher<List<Schedule>> loadSchedulesSuccess;
1517
ActionDispatcher<Object> loadSchedulesFailure;
1618
ActionDispatcher<AppTab> updateTabAction;

lib/containers/schedules_tab.dart

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1+
import 'dart:async';
2+
13
import 'package:betterstatmobile/actions/actions.dart';
24
import 'package:betterstatmobile/models/models.dart';
35
import 'package:betterstatmobile/presentation/schedule_list.dart';
46
import 'package:flutter/widgets.dart';
57
import 'package:flutter_built_redux/flutter_built_redux.dart';
68

7-
class SchedulesTab extends StoreConnector<AppState, AppActions, List<Schedule>> {
9+
class SchedulesTab
10+
extends StoreConnector<AppState, AppActions, List<Schedule>> {
811
SchedulesTab({Key key}) : super(key: key);
912

1013
@override
1114
Widget build(BuildContext context, List<Schedule> state, AppActions actions) {
1215
return ScheduleList(
1316
schedules: state,
14-
onRefresh: () async {
15-
await actions.fetchSchedulesAction();
17+
onRefresh: (Completer<Null> completer) {
18+
actions.fetchSchedulesAction(completer);
19+
return completer.future;
1620
},
1721
onRemove: (schedule) {
1822
actions.deleteScheduleAction(schedule.id);
@@ -25,4 +29,4 @@ class SchedulesTab extends StoreConnector<AppState, AppActions, List<Schedule>>
2529

2630
@override
2731
List<Schedule> connect(AppState state) => state.schedulesSelector;
28-
}
32+
}

lib/main.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:async';
2+
13
import 'package:betterstatmobile/actions/actions.dart';
24
import 'package:betterstatmobile/containers/add_schedule.dart';
35
import 'package:betterstatmobile/localization.dart';
@@ -41,7 +43,7 @@ class BetterstatAppState extends State<BetterstatApp> {
4143
void initState() {
4244
store = widget.store;
4345

44-
store.actions.fetchSchedulesAction();
46+
store.actions.fetchSchedulesAction(Completer<Null>());
4547

4648
super.initState();
4749
}

lib/middleware/store_schedules_middleware.dart

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:async';
2+
13
import 'package:betterstatmobile/repository/SchedulesRepository.dart';
24
import 'package:built_redux/built_redux.dart';
35
import 'package:betterstatmobile/actions/actions.dart';
@@ -10,7 +12,7 @@ Middleware<AppState, AppStateBuilder, AppActions>
1012
]) {
1113
return (MiddlewareBuilder<AppState, AppStateBuilder, AppActions>()
1214
..add(AppActionsNames.fetchSchedulesAction,
13-
createFetchSchedules(repository))
15+
createFetchSchedules<Completer<Null>>(repository))
1416
..add(AppActionsNames.addScheduleAction,
1517
createSaveSchedule<Schedule>(repository))
1618
// ..add(AppActionsNames.loadSchedulesSuccess,
@@ -42,6 +44,7 @@ MiddlewareHandler<AppState, AppStateBuilder, AppActions, T>
4244
repository.saveSchedule(pl.updatedSchedule, pl.id);
4345
};
4446
}
47+
4548
MiddlewareHandler<AppState, AppStateBuilder, AppActions, T>
4649
createSaveSchedule<T>(SchedulesRepository repository) {
4750
return (MiddlewareApi<AppState, AppStateBuilder, AppActions> api,
@@ -52,16 +55,15 @@ MiddlewareHandler<AppState, AppStateBuilder, AppActions, T>
5255
};
5356
}
5457

55-
MiddlewareHandler<AppState, AppStateBuilder, AppActions, Null>
56-
createFetchSchedules(SchedulesRepository repository) {
58+
MiddlewareHandler<AppState, AppStateBuilder, AppActions, T>
59+
createFetchSchedules<T>(SchedulesRepository repository) {
5760
return (MiddlewareApi<AppState, AppStateBuilder, AppActions> api,
58-
ActionHandler next, Action<Null> action) {
59-
if (api.state.isLoading) {
60-
repository.loadSchedules().then((schedules) {
61-
return api.actions.loadSchedulesSuccess(schedules);
62-
}).catchError(api.actions.loadSchedulesFailure);
63-
}
64-
61+
ActionHandler next, Action<T> action) {
62+
repository.loadSchedules().then((schedules) {
63+
var loadingCallback = action.payload as Completer<Null>;
64+
loadingCallback.complete();
65+
return api.actions.loadSchedulesSuccess(schedules);
66+
}).catchError(api.actions.loadSchedulesFailure);
6567
next(action);
6668
};
6769
}

lib/presentation/schedule_list.dart

+36-24
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by the MIT license that can be found
33
// in the LICENSE file.
44

5+
import 'dart:async';
6+
57
import 'package:betterstatmobile/containers/app_loading.dart';
68
import 'package:betterstatmobile/containers/schedule_details.dart';
79
import 'package:betterstatmobile/localization.dart';
@@ -18,7 +20,7 @@ class ScheduleList extends StatelessWidget {
1820
final List<Schedule> schedules;
1921
final Function(Schedule) onRemove;
2022
final Function(Schedule) onUndoRemove;
21-
final Function() onRefresh;
23+
Future<Null> Function(Completer<Null>) onRefresh;
2224

2325
ScheduleList({
2426
@required this.schedules,
@@ -30,33 +32,42 @@ class ScheduleList extends StatelessWidget {
3032
@override
3133
Widget build(BuildContext context) {
3234
return AppLoading(builder: (context, loading) {
33-
return loading
34-
? Center(
35-
key: BetterstatKeys.schedulesLoading,
36-
child: CircularProgressIndicator(
37-
key: BetterstatKeys.statsLoading,
38-
))
39-
: RefreshIndicator(
35+
return RefreshIndicator(
4036
key: _refreshIndicatorKey,
41-
onRefresh: () async {await onRefresh();},
42-
child: Container(
43-
child: ListView.builder(
44-
key: BetterstatKeys.scheduleList,
45-
itemCount: schedules.length,
46-
itemBuilder: (BuildContext context, int index) {
47-
final schedule = schedules[index];
37+
onRefresh: () => onRefresh(Completer<Null>()),
38+
child: Container(
39+
child: ListView.builder(
40+
key: BetterstatKeys.scheduleList,
41+
itemCount: schedules.length,
42+
itemBuilder: (BuildContext context, int index) {
43+
final schedule = schedules[index];
4844

49-
return ScheduleItem(
50-
schedule: schedule,
51-
onTap: () => {},
52-
);
53-
},
54-
),
55-
),
56-
);
45+
return ScheduleItem(
46+
schedule: schedule,
47+
onTap: () => {},
48+
);
49+
},
50+
),
51+
),
52+
);
5753
});
5854
}
5955

56+
Future waitWhile(bool Function() test,
57+
[Duration pollInterval = Duration.zero]) {
58+
var completer = Completer();
59+
void check() {
60+
if (!test()) {
61+
completer.complete();
62+
} else {
63+
Timer(pollInterval, check);
64+
}
65+
}
66+
67+
check();
68+
return completer.future;
69+
}
70+
6071
void _removeSchedule(BuildContext context, Schedule schedule) {
6172
onRemove(schedule);
6273

@@ -90,7 +101,8 @@ class ScheduleList extends StatelessWidget {
90101
key: BetterstatKeys.snackbar,
91102
duration: Duration(seconds: 2),
92103
content: Text(
93-
BetterstatLocalizations.of(context).scheduleDeleted(schedule.name),
104+
BetterstatLocalizations.of(context)
105+
.scheduleDeleted(schedule.name),
94106
maxLines: 1,
95107
overflow: TextOverflow.ellipsis,
96108
),

lib/reducers/reducers.dart

+7-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ var reducerBuilder = ReducerBuilder<AppState, AppStateBuilder>()
1010
..add(AppActionsNames.loadSchedulesSuccess, schedulesLoaded)
1111
..add(AppActionsNames.loadSchedulesFailure, schedulesLoadFailed);
1212

13-
void addSchedule(AppState state, Action<Schedule> action, AppStateBuilder builder) {
13+
void addSchedule(
14+
AppState state, Action<Schedule> action, AppStateBuilder builder) {
1415
builder.schedules.add(action.payload);
1516
}
1617

@@ -27,6 +28,7 @@ void schedulesLoaded(
2728
AppState state, Action<List<Schedule>> action, AppStateBuilder builder) {
2829
builder
2930
..isLoading = false
31+
..schedules.clear()
3032
..schedules.addAll(action.payload);
3133
}
3234

@@ -39,6 +41,7 @@ void schedulesLoadFailed(
3941

4042
void updateSchedule(AppState state, Action<UpdateScheduleActionPayload> action,
4143
AppStateBuilder builder) {
42-
builder.schedules.map((schedule) =>
43-
schedule.id == action.payload.id ? action.payload.updatedSchedule : schedule);
44-
}
44+
builder.schedules.map((schedule) => schedule.id == action.payload.id
45+
? action.payload.updatedSchedule
46+
: schedule);
47+
}

0 commit comments

Comments
 (0)