app/lib/base/ui_model.dart

142 lines
3.4 KiB
Dart
Raw Normal View History

2023-10-09 09:32:07 +08:00
import 'package:flutter_riverpod/flutter_riverpod.dart';
2024-01-13 17:29:41 +08:00
import 'package:grpc/grpc.dart';
2023-10-09 09:32:07 +08:00
import 'ui.dart';
2024-03-01 20:59:43 +08:00
import '../common/utils/log.dart' as log_utils;
2023-10-09 09:32:07 +08:00
export '../common/utils/base_utils.dart';
export 'ui.dart';
class BaseUIModel extends ChangeNotifier {
String uiErrorMsg = "";
bool _isDisposed = false;
bool get mounted => !_isDisposed;
BuildContext? context;
BaseUIModel() {
initModel();
}
@mustCallSuper
void initModel() {
dPrint("[base] <$runtimeType> Model Init");
loadData();
}
@mustCallSuper
@override
void dispose() {
_isDisposed = true;
_childUIModels?.forEach((k, value) {
(value as BaseUIModel).dispose();
_childUIModels?[k] = null;
});
dPrint("[base] <$runtimeType> Model Disposed");
super.dispose();
}
Future loadData() async {}
Future reloadData() async {
return loadData();
}
Future onErrorReloadData() async {
return loadData();
}
@override
void notifyListeners() {
if (!mounted) return;
super.notifyListeners();
}
Future<T?> handleError<T>(Future<T> Function() requestFunc,
2024-01-07 14:57:49 +08:00
{bool showFullScreenError = false,
String? errorOverride,
bool noAlert = false}) async {
2023-10-09 09:32:07 +08:00
uiErrorMsg = "";
if (mounted) notifyListeners();
try {
return await requestFunc();
} catch (e) {
dPrint("$runtimeType.handleError Error:$e");
String errorMsg = "Unknown Error";
2024-01-13 17:29:41 +08:00
if (e is GrpcError) {
2024-01-14 20:47:15 +08:00
errorMsg = "远程服务器消息: ${e.message ?? "Unknown Error"}";
2024-01-13 17:29:41 +08:00
} else {
errorMsg = e.toString();
}
2023-10-09 09:32:07 +08:00
if (showFullScreenError) {
uiErrorMsg = errorMsg;
notifyListeners();
return null;
}
2024-01-07 18:52:06 +08:00
if (!noAlert) {
showToast(context!, errorOverride ?? errorMsg,
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context!).size.width * .6,
2024-01-13 17:29:41 +08:00
),
title: "出现错误!");
2024-01-07 18:52:06 +08:00
}
2023-10-09 09:32:07 +08:00
}
return null;
}
Map<dynamic, dynamic>? _childUIModels;
Map<dynamic, dynamic>? _childUIProviders;
BaseUIModel? onCreateChildUIModel(modelKey) => null;
dynamic _getChildUIModel(modelKey) {
_childUIModels ??= {};
final cachedModel = _childUIModels![modelKey];
if (cachedModel != null) {
return (cachedModel);
}
final newModel = onCreateChildUIModel(modelKey);
_childUIModels![modelKey] = newModel!;
return newModel;
}
ChangeNotifierProvider<M> getChildUIModelProviders<M extends BaseUIModel>(
modelKey) {
_childUIProviders ??= {};
if (_childUIProviders![modelKey] == null) {
_childUIProviders![modelKey] = ChangeNotifierProvider<M>((ref) {
final c = (_getChildUIModel(modelKey) as M);
return c..context = context;
});
}
return _childUIProviders![modelKey]!;
}
2024-02-06 20:19:53 +08:00
T? getCreatedChildUIModel<T extends BaseUIModel>(String modelKey,
{bool create = false}) {
if (create && _childUIModels?[modelKey] == null) {
2024-01-14 20:47:15 +08:00
_getChildUIModel(modelKey);
}
2023-10-09 09:32:07 +08:00
return _childUIModels?[modelKey] as T?;
}
Future<void> reloadAllChildModels() async {
if (_childUIModels == null) return;
final futureList = <Future>[];
for (var value in _childUIModels!.entries) {
futureList.add(value.value.reloadData());
}
await Future.wait(futureList);
notifyListeners();
}
dismissKeyBoard() {
FocusManager.instance.primaryFocus?.unfocus();
}
2024-03-01 20:59:43 +08:00
dPrint(src) {
log_utils.dPrint("<$runtimeType> $src");
}
2023-10-09 09:32:07 +08:00
}