git-touch-android-ios-app/lib/scaffolds/tab_stateful.dart

118 lines
2.5 KiB
Dart
Raw Normal View History

2019-09-25 11:06:36 +02:00
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:git_touch/scaffolds/tab.dart';
2019-09-25 12:47:34 +02:00
import 'package:git_touch/scaffolds/utils.dart';
2019-09-25 11:06:36 +02:00
class TabStatefulScaffold<T> extends StatefulWidget {
final Widget title;
final Widget Function(T payload, int activeTab) bodyBuilder;
2019-09-30 11:37:51 +02:00
final Future<T> Function(int activeTab) fetchData;
2019-09-25 11:06:36 +02:00
final List<String> tabs;
2019-09-30 11:37:51 +02:00
final Widget Function(T payload, void Function() refresh) actionBuilder;
2019-09-25 11:06:36 +02:00
TabStatefulScaffold({
@required this.title,
@required this.bodyBuilder,
2019-09-30 11:37:51 +02:00
@required this.fetchData,
2019-09-25 11:06:36 +02:00
@required this.tabs,
2019-09-30 11:37:51 +02:00
this.actionBuilder,
2019-09-25 11:06:36 +02:00
});
@override
2019-12-03 04:26:08 +01:00
_TabStatefulScaffoldState<T> createState() => _TabStatefulScaffoldState();
2019-09-25 11:06:36 +02:00
}
class _TabStatefulScaffoldState<T> extends State<TabStatefulScaffold<T>> {
bool _loading;
T _payload0;
T _payload1;
T _payload2;
String _error = '';
int _activeTab = 0;
T _getPayload(int selected) {
switch (selected) {
case 0:
return _payload0;
case 1:
return _payload1;
case 2:
return _payload2;
default:
throw '';
}
}
T get _payload => _getPayload(_activeTab);
set _payload(T v) {
switch (_activeTab) {
case 0:
_payload0 = v;
break;
case 1:
_payload1 = v;
break;
case 2:
_payload2 = v;
break;
}
}
@override
void initState() {
super.initState();
_refresh();
}
Future<void> _refresh() async {
try {
setState(() {
_error = '';
_loading = true;
});
2019-09-30 11:37:51 +02:00
_payload = await widget.fetchData(_activeTab);
2019-09-25 11:06:36 +02:00
} catch (err) {
_error = err.toString();
throw err;
} finally {
if (mounted) {
setState(() {
_loading = false;
});
}
}
}
Future<void> _switch(int selected) async {
2019-09-27 11:28:10 +02:00
if (_loading) return;
2019-09-25 11:06:36 +02:00
setState(() {
_activeTab = selected;
});
if (_getPayload(selected) == null) {
await _refresh();
}
}
@override
Widget build(BuildContext context) {
return TabScaffold(
title: widget.title,
2019-10-03 04:01:54 +02:00
action: widget.actionBuilder == null
2019-09-30 11:37:51 +02:00
? null
: widget.actionBuilder(_payload, _refresh),
2019-09-25 12:47:34 +02:00
tabs: widget.tabs,
activeTab: _activeTab,
onTabSwitch: _switch,
2019-09-25 11:06:36 +02:00
onRefresh: _refresh,
2019-09-25 12:47:34 +02:00
body: ErrorLoadingWrapper(
bodyBuilder: () => widget.bodyBuilder(_payload, _activeTab),
error: _error,
loading: _payload == null,
reload: _refresh,
),
2019-09-25 11:06:36 +02:00
);
}
}