mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-06-29 03:23:54 +08:00
re init
This commit is contained in:
212
lib/base/ui.dart
Normal file
212
lib/base/ui.dart
Normal file
@ -0,0 +1,212 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/main.dart';
|
||||
import 'package:starcitizen_doctor/widgets/my_page_route.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'ui_model.dart';
|
||||
|
||||
export '../common/utils/base_utils.dart';
|
||||
export '../widgets/widgets.dart';
|
||||
export 'package:fluent_ui/fluent_ui.dart';
|
||||
|
||||
class BaseUIContainer extends ConsumerStatefulWidget {
|
||||
final ConsumerState<BaseUIContainer> Function() uiCreate;
|
||||
final dynamic Function() modelCreate;
|
||||
|
||||
const BaseUIContainer(
|
||||
{Key? key, required this.uiCreate, required this.modelCreate})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
// ignore: no_logic_in_create_state
|
||||
ConsumerState<BaseUIContainer> createState() => uiCreate();
|
||||
|
||||
Future push(BuildContext context) {
|
||||
return Navigator.push(context, makeRoute(context, this));
|
||||
}
|
||||
|
||||
// Future pushShowModalBottomSheet(BuildContext context) {
|
||||
// return showModalBottomSheet(
|
||||
// context: context,
|
||||
// isScrollControlled: true,
|
||||
// builder: (BuildContext context) {
|
||||
// return this;
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
|
||||
/// 获取路由
|
||||
FluentPageRoute makeRoute(
|
||||
BuildContext context, BaseUIContainer baseUIContainer) {
|
||||
return MyPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return baseUIContainer;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Future pushAndRemoveUntil(BuildContext context) {
|
||||
// return Navigator.pushAndRemoveUntil(context,
|
||||
// MaterialPageRoute(builder: (BuildContext context) {
|
||||
// return this;
|
||||
// }), (_) => false);
|
||||
// }
|
||||
}
|
||||
|
||||
abstract class BaseUI<T extends BaseUIModel>
|
||||
extends ConsumerState<BaseUIContainer> {
|
||||
BaseUIModel? _needDisposeModel;
|
||||
late final ChangeNotifierProvider<T> provider = bindUIModel();
|
||||
|
||||
// final GlobalKey<ScaffoldState> scaffoldState = GlobalKey();
|
||||
// RefreshController? refreshController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// get model
|
||||
final model = ref.watch(provider);
|
||||
return buildBody(context, model)!;
|
||||
}
|
||||
|
||||
String getUITitle(BuildContext context, T model);
|
||||
|
||||
Widget? buildBody(
|
||||
BuildContext context,
|
||||
T model,
|
||||
);
|
||||
|
||||
Widget? getBottomNavigationBar(BuildContext context, T model) => null;
|
||||
|
||||
Color? getBackgroundColor(BuildContext context, T model) => null;
|
||||
|
||||
Widget? getFloatingActionButton(BuildContext context, T model) => null;
|
||||
|
||||
FloatingActionButtonLocation? getFloatingActionButtonLocation(
|
||||
BuildContext context, T model) =>
|
||||
null;
|
||||
|
||||
bool getDrawerEnableOpenDragGesture(BuildContext context, T model) => true;
|
||||
|
||||
Widget? getDrawer(BuildContext context, T model) => null;
|
||||
|
||||
Widget makeDefaultPage(BuildContext context, T model,
|
||||
{Widget? titleRow,
|
||||
List<Widget>? actions,
|
||||
Widget? content,
|
||||
bool automaticallyImplyLeading = true}) {
|
||||
return NavigationView(
|
||||
pane: NavigationPane(
|
||||
size: const NavigationPaneSize(openWidth: 0),
|
||||
),
|
||||
appBar: NavigationAppBar(
|
||||
automaticallyImplyLeading: automaticallyImplyLeading,
|
||||
title: DragToMoveArea(
|
||||
child: titleRow ??
|
||||
Row(
|
||||
children: [
|
||||
Text(getUITitle(context, model)),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [...?actions, const WindowButtons()],
|
||||
)),
|
||||
paneBodyBuilder: (
|
||||
PaneItem? item,
|
||||
Widget? body,
|
||||
) {
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: content ?? makeLoading(context),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@mustCallSuper
|
||||
@override
|
||||
void initState() {
|
||||
dPrint("[base] <$runtimeType> UI Init");
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@mustCallSuper
|
||||
@override
|
||||
void dispose() {
|
||||
dPrint("[base] <$runtimeType> UI Disposed");
|
||||
_needDisposeModel?.dispose();
|
||||
_needDisposeModel = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// 关闭键盘
|
||||
dismissKeyBoard() {
|
||||
FocusManager.instance.primaryFocus?.unfocus();
|
||||
}
|
||||
|
||||
Widget errorBody(BuildContext context, Widget? child, T model) {
|
||||
if (model.uiErrorMsg.isNotEmpty) {
|
||||
// 全局错误信息
|
||||
return InkWell(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"Error",
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
Text(model.uiErrorMsg),
|
||||
],
|
||||
)),
|
||||
onTap: () async {
|
||||
await model.onErrorReloadData();
|
||||
},
|
||||
);
|
||||
}
|
||||
if (child == null) return makeLoading(context);
|
||||
return child;
|
||||
}
|
||||
|
||||
// void updateStatusBarIconColor(BuildContext context) {
|
||||
// SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
// statusBarBrightness: Theme.of(context).brightness,
|
||||
// statusBarIconBrightness: getAndroidIconBrightness(context),
|
||||
// ));
|
||||
// }
|
||||
|
||||
ChangeNotifierProvider<T> bindUIModel() {
|
||||
final createdModel = widget.modelCreate();
|
||||
if (createdModel is T) {
|
||||
_needDisposeModel = createdModel;
|
||||
return ChangeNotifierProvider<T>((ref) {
|
||||
return createdModel..context = context;
|
||||
});
|
||||
}
|
||||
return createdModel;
|
||||
}
|
||||
|
||||
// Widget pullToRefreshBody(
|
||||
// {required BaseUIModel model, required Widget child}) {
|
||||
// refreshController ??= RefreshController();
|
||||
// return AppSmartRefresher(
|
||||
// enablePullUp: false,
|
||||
// controller: refreshController,
|
||||
// onRefresh: () async {
|
||||
// await model.reloadData();
|
||||
// refreshController?.refreshCompleted();
|
||||
// },
|
||||
// child: child,
|
||||
// );
|
||||
// }
|
||||
|
||||
makeSvgColor(Color color, {BlendMode blendMode = BlendMode.color}) {
|
||||
return ui.ColorFilter.mode(color, blendMode);
|
||||
}
|
||||
}
|
125
lib/base/ui_model.dart
Normal file
125
lib/base/ui_model.dart
Normal file
@ -0,0 +1,125 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'ui.dart';
|
||||
|
||||
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,
|
||||
{bool showFullScreenError = false, String? errorOverride}) async {
|
||||
uiErrorMsg = "";
|
||||
if (mounted) notifyListeners();
|
||||
try {
|
||||
return await requestFunc();
|
||||
} catch (e) {
|
||||
dPrint("$runtimeType.handleError Error:$e");
|
||||
String errorMsg = "Unknown Error";
|
||||
// if (e is AppHttpResultData && stringIsNotEmpty(e.msg)) {
|
||||
// errorMsg = e.msg!;
|
||||
// return null;
|
||||
// } else {
|
||||
// errorMsg = e.toString();
|
||||
// }
|
||||
errorMsg = e.toString();
|
||||
if (showFullScreenError) {
|
||||
uiErrorMsg = errorMsg;
|
||||
notifyListeners();
|
||||
return null;
|
||||
}
|
||||
showToast(context!, errorOverride ?? errorMsg);
|
||||
}
|
||||
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]!;
|
||||
}
|
||||
|
||||
T? getCreatedChildUIModel<T extends BaseUIModel>(String modelKey) {
|
||||
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();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user