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

116 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;
2021-05-16 09:16:35 +02:00
final Widget Function(T payload, void Function() refresh)? actionBuilder;
2019-09-25 11:06:36 +02:00
TabStatefulScaffold({
2021-05-16 09:16:35 +02:00
required this.title,
required this.bodyBuilder,
required this.fetchData,
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
}
2021-05-30 17:55:57 +02:00
class _TabStatefulScaffoldState<T> extends State<TabStatefulScaffold<T>> {
2021-05-16 09:16:35 +02:00
late bool _loading;
T? _payload0;
T? _payload1;
T? _payload2;
2019-09-25 11:06:36 +02:00
String _error = '';
int _activeTab = 0;
2021-05-16 09:16:35 +02:00
T? _getPayload(int selected) {
2019-09-25 11:06:36 +02:00
switch (selected) {
case 0:
return _payload0;
case 1:
return _payload1;
case 2:
return _payload2;
default:
throw '';
}
}
2021-05-16 09:16:35 +02:00
T? get _payload => _getPayload(_activeTab);
2019-09-25 11:06:36 +02:00
2021-05-16 09:16:35 +02:00
set _payload(T? v) {
2019-09-25 11:06:36 +02:00
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;
});
}
}
}
@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
2021-05-30 17:55:57 +02:00
: widget.actionBuilder!(_payload!, _refresh),
2019-09-25 12:47:34 +02:00
tabs: widget.tabs,
activeTab: _activeTab,
2021-05-16 09:16:35 +02:00
onTabSwitch: (selected) async {
if (_loading) return;
setState(() {
_activeTab = selected;
});
if (_getPayload(selected) == null) {
await _refresh();
}
},
2019-09-25 11:06:36 +02:00
onRefresh: _refresh,
2019-09-25 12:47:34 +02:00
body: ErrorLoadingWrapper(
2021-05-30 17:55:57 +02:00
bodyBuilder: () => widget.bodyBuilder(_payload!, _activeTab),
2019-09-25 12:47:34 +02:00
error: _error,
loading: _payload == null,
reload: _refresh,
),
2019-09-25 11:06:36 +02:00
);
}
}