diff --git a/assets/images/add_btn_svip.png b/assets/images/add_btn_svip.png new file mode 100644 index 0000000..fef251c Binary files /dev/null and b/assets/images/add_btn_svip.png differ diff --git a/assets/images/icon_add_file.png b/assets/images/icon_add_file.png new file mode 100644 index 0000000..94505fc Binary files /dev/null and b/assets/images/icon_add_file.png differ diff --git a/assets/images/js.png b/assets/images/js.png new file mode 100644 index 0000000..91d1188 Binary files /dev/null and b/assets/images/js.png differ diff --git a/assets/images/json.png b/assets/images/json.png new file mode 100644 index 0000000..f39a8c4 Binary files /dev/null and b/assets/images/json.png differ diff --git a/assets/images/other.png b/assets/images/other.png new file mode 100644 index 0000000..f8cffc3 Binary files /dev/null and b/assets/images/other.png differ diff --git a/assets/images/py.png b/assets/images/py.png new file mode 100644 index 0000000..2213506 Binary files /dev/null and b/assets/images/py.png differ diff --git a/assets/images/shell.png b/assets/images/shell.png new file mode 100644 index 0000000..9563d70 Binary files /dev/null and b/assets/images/shell.png differ diff --git a/assets/images/ts.png b/assets/images/ts.png new file mode 100644 index 0000000..0bc3036 Binary files /dev/null and b/assets/images/ts.png differ diff --git a/lib/base/base_state_widget.dart b/lib/base/base_state_widget.dart index fb9e9df..d005ff6 100644 --- a/lib/base/base_state_widget.dart +++ b/lib/base/base_state_widget.dart @@ -24,7 +24,9 @@ class BaseStateWidget extends ConsumerStatefulWidget { _BaseStateWidgetState createState() => _BaseStateWidgetState(); } -class _BaseStateWidgetState extends ConsumerState> with LazyLoadState> { +class _BaseStateWidgetState + extends ConsumerState> + with LazyLoadState> { @override Widget build(BuildContext context) { var viewModel = ref.watch(widget.model); diff --git a/lib/base/http/api.dart b/lib/base/http/api.dart index 802ff6c..805bba1 100644 --- a/lib/base/http/api.dart +++ b/lib/base/http/api.dart @@ -89,21 +89,24 @@ class Api { ); } - static Future> startTasks(List crons) async { + static Future> startTasks( + List crons) async { return await Http.put( Url.runTasks, crons, ); } - static Future> stopTasks(List crons) async { + static Future> stopTasks( + List crons) async { return await Http.put( Url.stopTasks, crons, ); } - static Future> updatePassword(String name, String password) async { + static Future> updatePassword( + String name, String password) async { return await Http.put( Url.updatePassword, { @@ -127,7 +130,11 @@ class Api { int? id, String? nId, }) async { - var data = {"name": name, "command": command, "schedule": cron}; + var data = { + "name": name, + "command": command, + "schedule": cron + }; if (id != null || nId != null) { if (id != null) { @@ -195,7 +202,8 @@ class Api { ); } - static Future> saveFile(String name, String content) async { + static Future> saveFile( + String name, String content) async { return await Http.post( Url.saveFile, {"content": content, "name": name}, @@ -260,7 +268,8 @@ class Api { ); } - static Future> moveEnv(String id, int fromIndex, int toIndex) async { + static Future> moveEnv( + String id, int fromIndex, int toIndex) async { return await Http.put( Url.envMove(id), {"fromIndex": fromIndex, "toIndex": toIndex}, @@ -275,10 +284,12 @@ class Api { } static Future>> taskLog() async { - return await Http.get>(Url.taskLog, null, serializationName: Utils.isUpperVersion2_12_2() ? "data" : "dirs"); + return await Http.get>(Url.taskLog, null, + serializationName: Utils.isUpperVersion2_12_2() ? "data" : "dirs"); } - static Future> taskLogDetail(String name, String path) async { + static Future> taskLogDetail( + String name, String path) async { if (Utils.isUpperVersion2_13_0()) { return await Http.get( Url.taskLogDetail + name + "?path=" + path, @@ -300,7 +311,8 @@ class Api { ); } - static Future> updateScript(String name, String path, String content) async { + static Future> updateScript( + String name, String path, String content) async { return await Http.put( Url.scriptDetail, { @@ -311,7 +323,8 @@ class Api { ); } - static Future> delScript(String name, String path) async { + static Future> delScript( + String name, String path) async { return await Http.delete( Url.scriptDetail, { @@ -321,7 +334,8 @@ class Api { ); } - static Future> scriptDetail(String name, String? path) async { + static Future> scriptDetail( + String name, String? path) async { return await Http.get( Url.scriptDetail + name, { @@ -330,7 +344,8 @@ class Api { ); } - static Future>> dependencies(String type) async { + static Future>> dependencies( + String type) async { return await Http.get>( Url.dependencies, { @@ -339,7 +354,8 @@ class Api { ); } - static Future> dependencyReinstall(String id) async { + static Future> dependencyReinstall( + String id) async { return await Http.put( Url.dependencies, [id], @@ -353,7 +369,8 @@ class Api { ); } - static Future> addDependency(String name, int type) async { + static Future> addDependency( + String name, int type) async { return await Http.post( Url.dependencies, [ @@ -365,7 +382,8 @@ class Api { ); } - static Future> addScript(String name, String path, String content) async { + static Future> addScript( + String name, String path, String content) async { return await Http.post( Url.addScript, { diff --git a/lib/base/http/http.dart b/lib/base/http/http.dart index 52c5dbb..915cd0a 100644 --- a/lib/base/http/http.dart +++ b/lib/base/http/http.dart @@ -122,7 +122,8 @@ class Http { if (!pushedLoginPage) { "身份已过期,请重新登录".toast(); pushedLoginPage = true; - navigatorState.currentState?.pushNamedAndRemoveUntil(Routes.routeLogin, (route) => false); + navigatorState.currentState + ?.pushNamedAndRemoveUntil(Routes.routeLogin, (route) => false); } } @@ -136,9 +137,15 @@ class Http { } if (e.response != null && e.response!.data != null) { - return HttpResponse(success: false, message: e.response?.data["message"] ?? e.message, code: e.response?.data["code"] ?? 0); + return HttpResponse( + success: false, + message: e.response?.data["message"] ?? e.message, + code: e.response?.data["code"] ?? 0); } else { - return HttpResponse(success: false, message: e.message, code: e.response?.statusCode ?? 0); + return HttpResponse( + success: false, + message: e.message, + code: e.response?.statusCode ?? 0); } } @@ -223,7 +230,8 @@ class HttpResponse { late int code; T? bean; - HttpResponse({required this.success, this.message, required this.code, this.bean}); + HttpResponse( + {required this.success, this.message, required this.code, this.bean}); } class DeserializeAction { diff --git a/lib/base/http/token_interceptor.dart b/lib/base/http/token_interceptor.dart index cb58241..821e618 100644 --- a/lib/base/http/token_interceptor.dart +++ b/lib/base/http/token_interceptor.dart @@ -7,8 +7,7 @@ import '../userinfo_viewmodel.dart'; class TokenInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { - options.headers["User-Agent"] = - "qinglong_client"; + options.headers["User-Agent"] = "qinglong_client"; options.headers["Content-Type"] = "application/json;charset=UTF-8"; diff --git a/lib/base/http/url.dart b/lib/base/http/url.dart index 47a846d..a96842f 100644 --- a/lib/base/http/url.dart +++ b/lib/base/http/url.dart @@ -14,70 +14,127 @@ class Url { static const updatePassword = "/api/user"; - static get tasks => getIt().useSecretLogined ? "/open/crons" : "/api/crons"; + static get tasks => getIt().useSecretLogined + ? "/open/crons" + : "/api/crons"; - static get runTasks => getIt().useSecretLogined ? "/open/crons/run" : "/api/crons/run"; + static get runTasks => getIt().useSecretLogined + ? "/open/crons/run" + : "/api/crons/run"; - static get stopTasks => getIt().useSecretLogined ? "/open/crons/stop" : "/api/crons/stop"; + static get stopTasks => getIt().useSecretLogined + ? "/open/crons/stop" + : "/api/crons/stop"; - static get taskDetail => getIt().useSecretLogined ? "/open/crons/" : "/api/crons/"; + static get taskDetail => getIt().useSecretLogined + ? "/open/crons/" + : "/api/crons/"; - static get addTask => getIt().useSecretLogined ? "/open/crons" : "/api/crons"; + static get addTask => getIt().useSecretLogined + ? "/open/crons" + : "/api/crons"; - static get pinTask => getIt().useSecretLogined ? "/open/crons/pin" : "/api/crons/pin"; + static get pinTask => getIt().useSecretLogined + ? "/open/crons/pin" + : "/api/crons/pin"; - static get unpinTask => getIt().useSecretLogined ? "/open/crons/unpin" : "/api/crons/unpin"; + static get unpinTask => getIt().useSecretLogined + ? "/open/crons/unpin" + : "/api/crons/unpin"; - static get enableTask => getIt().useSecretLogined ? "/open/crons/enable" : "/api/crons/enable"; + static get enableTask => getIt().useSecretLogined + ? "/open/crons/enable" + : "/api/crons/enable"; - static get disableTask => getIt().useSecretLogined ? "/open/crons/disable" : "/api/crons/disable"; + static get disableTask => getIt().useSecretLogined + ? "/open/crons/disable" + : "/api/crons/disable"; - static get files => getIt().useSecretLogined ? "/open/configs/files" : "/api/configs/files"; + static get files => getIt().useSecretLogined + ? "/open/configs/files" + : "/api/configs/files"; - static get configContent => getIt().useSecretLogined ? "/open/configs/" : "/api/configs/"; + static get configContent => getIt().useSecretLogined + ? "/open/configs/" + : "/api/configs/"; - static get saveFile => getIt().useSecretLogined ? "/open/configs/save" : "/api/configs/save"; + static get saveFile => getIt().useSecretLogined + ? "/open/configs/save" + : "/api/configs/save"; - static get envs => getIt().useSecretLogined ? "/open/envs" : "/api/envs"; + static get envs => + getIt().useSecretLogined ? "/open/envs" : "/api/envs"; - static get addEnv => getIt().useSecretLogined ? "/open/envs" : "/api/envs"; + static get addEnv => + getIt().useSecretLogined ? "/open/envs" : "/api/envs"; - static get delEnv => getIt().useSecretLogined ? "/open/envs" : "/api/envs"; + static get delEnv => + getIt().useSecretLogined ? "/open/envs" : "/api/envs"; - static get disableEnvs => getIt().useSecretLogined ? "/open/envs/disable" : "/api/envs/disable"; + static get disableEnvs => getIt().useSecretLogined + ? "/open/envs/disable" + : "/api/envs/disable"; - static get enableEnvs => getIt().useSecretLogined ? "/open/envs/enable" : "/api/envs/enable"; + static get enableEnvs => getIt().useSecretLogined + ? "/open/envs/enable" + : "/api/envs/enable"; - static get loginLog => getIt().useSecretLogined ? "/open/user/login-log" : "/api/user/login-log"; + static get loginLog => getIt().useSecretLogined + ? "/open/user/login-log" + : "/api/user/login-log"; - static get taskLog => getIt().useSecretLogined ? "/open/logs" : "/api/logs"; + static get taskLog => + getIt().useSecretLogined ? "/open/logs" : "/api/logs"; - static get taskLogDetail => getIt().useSecretLogined ? "/open/logs/" : "/api/logs/"; + static get taskLogDetail => getIt().useSecretLogined + ? "/open/logs/" + : "/api/logs/"; - static get scripts => getIt().useSecretLogined ? "/open/scripts/files" : "/api/scripts/files"; + static get scripts => getIt().useSecretLogined + ? "/open/scripts/files" + : "/api/scripts/files"; - static get scripts2 => getIt().useSecretLogined ? "/open/scripts" : "/api/scripts"; + static get scripts2 => getIt().useSecretLogined + ? "/open/scripts" + : "/api/scripts"; - static get scriptUpdate => getIt().useSecretLogined ? "/open/scripts" : "/api/scripts"; + static get scriptUpdate => getIt().useSecretLogined + ? "/open/scripts" + : "/api/scripts"; - static get scriptDetail => getIt().useSecretLogined ? "/open/scripts/" : "/api/scripts/"; + static get scriptDetail => getIt().useSecretLogined + ? "/open/scripts/" + : "/api/scripts/"; - static get dependencies => getIt().useSecretLogined ? "/open/dependencies" : "/api/dependencies"; + static get dependencies => getIt().useSecretLogined + ? "/open/dependencies" + : "/api/dependencies"; - static get addScript => getIt().useSecretLogined ? "/open/scripts" : "/api/scripts"; + static get addScript => getIt().useSecretLogined + ? "/open/scripts" + : "/api/scripts"; - static get dependencyReinstall => getIt().useSecretLogined ? "/open/dependencies/reinstall" : "/api/dependencies/reinstall"; + static get dependencyReinstall => getIt().useSecretLogined + ? "/open/dependencies/reinstall" + : "/api/dependencies/reinstall"; static intimeLog(String cronId) { - return getIt().useSecretLogined ? "/open/crons/$cronId/log" : "/api/crons/$cronId/log"; + return getIt().useSecretLogined + ? "/open/crons/$cronId/log" + : "/api/crons/$cronId/log"; } static envMove(String envId) { - return getIt().useSecretLogined ? "/open/envs/$envId/move" : "/api/envs/$envId/move"; + return getIt().useSecretLogined + ? "/open/envs/$envId/move" + : "/api/envs/$envId/move"; } static bool inWhiteList(String path) { - if (path == login || path == loginByClientId || path == loginTwo || path == loginOld) { + if (path == login || + path == loginByClientId || + path == loginTwo || + path == loginOld) { return true; } return false; diff --git a/lib/base/routes.dart b/lib/base/routes.dart index d0b5293..b9425b2 100644 --- a/lib/base/routes.dart +++ b/lib/base/routes.dart @@ -71,7 +71,8 @@ class Routes { return MaterialPageRoute(builder: (context) => const AddTaskPage()); } case routeAddDependency: - return MaterialPageRoute(builder: (context) => const AddDependencyPage()); + return MaterialPageRoute( + builder: (context) => const AddDependencyPage()); case routeAddEnv: if (settings.arguments != null) { return MaterialPageRoute( diff --git a/lib/base/ui/ql_context_menu.dart b/lib/base/ui/ql_context_menu.dart index ea3c325..1e73d68 100644 --- a/lib/base/ui/ql_context_menu.dart +++ b/lib/base/ui/ql_context_menu.dart @@ -5,7 +5,8 @@ import 'dart:math' as math; import 'dart:ui' as ui; -import 'package:flutter/gestures.dart' show kMinFlingVelocity, kLongPressTimeout; +import 'package:flutter/gestures.dart' + show kMinFlingVelocity, kLongPressTimeout; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; @@ -42,7 +43,8 @@ typedef _ContextMenuPreviewBuilderChildless = Widget Function( // paintBounds in global coordinates. Rect _getRect(GlobalKey globalKey) { assert(globalKey.currentContext != null); - final RenderBox renderBoxContainer = globalKey.currentContext!.findRenderObject()! as RenderBox; + final RenderBox renderBoxContainer = + globalKey.currentContext!.findRenderObject()! as RenderBox; final Offset containerOffset = renderBoxContainer.localToGlobal( renderBoxContainer.paintBounds.topLeft, ); @@ -194,7 +196,8 @@ class QlCupertinoContextMenu extends StatefulWidget { State createState() => _QlCupertinoContextMenuState(); } -class _QlCupertinoContextMenuState extends State with TickerProviderStateMixin { +class _QlCupertinoContextMenuState extends State + with TickerProviderStateMixin { final GlobalKey _childGlobalKey = GlobalKey(); bool _childHidden = false; @@ -227,7 +230,8 @@ class _QlCupertinoContextMenuState extends State with Ti final double screenWidth = MediaQuery.of(context).size.width; final double center = screenWidth / 2; - final bool centerDividesChild = childRect.left < center && childRect.right > center; + final bool centerDividesChild = + childRect.left < center && childRect.right > center; final double distanceFromCenter = (center - childRect.center.dx).abs(); if (centerDividesChild && distanceFromCenter <= childRect.width / 4) { return _ContextMenuLocation.center; @@ -318,7 +322,8 @@ class _QlCupertinoContextMenuState extends State with Ti _openController.reverse(); } else { if (_openController.isDismissed) { - Navigator.of(context).pushNamed(Routes.routeTaskDetail, arguments: widget.bean); + Navigator.of(context) + .pushNamed(Routes.routeTaskDetail, arguments: widget.bean); } } } @@ -419,7 +424,8 @@ class _DecoyChild extends StatefulWidget { _DecoyChildState createState() => _DecoyChildState(); } -class _DecoyChildState extends State<_DecoyChild> with TickerProviderStateMixin { +class _DecoyChildState extends State<_DecoyChild> + with TickerProviderStateMixin { // TODO(justinmc): Dark mode support. // See https://github.com/flutter/flutter/issues/43211. static const Color _lightModeMaskColor = Color(0xFF888888); @@ -481,7 +487,9 @@ class _DecoyChildState extends State<_DecoyChild> with TickerProviderStateMixin } Widget _buildAnimation(BuildContext context, Widget? child) { - final Color color = widget.controller.status == AnimationStatus.reverse ? _masklessColor : _mask.value; + final Color color = widget.controller.status == AnimationStatus.reverse + ? _masklessColor + : _mask.value; return Positioned.fromRect( rect: _rect.value!, child: ShaderMask( @@ -538,7 +546,8 @@ class _ContextMenuRoute extends PopupRoute { // The duration of the transition used when a modal popup is shown. Eyeballed // from a physical device running iOS 13.1.2. - static const Duration _kModalPopupTransitionDuration = Duration(milliseconds: 335); + static const Duration _kModalPopupTransitionDuration = + Duration(milliseconds: 335); final List _actions; final _ContextMenuPreviewBuilderChildless? _builder; @@ -562,7 +571,8 @@ class _ContextMenuRoute extends PopupRoute { static final RectTween _rectTween = RectTween(); static final Animatable _rectAnimatable = _rectTween.chain(_curve); static final RectTween _rectTweenReverse = RectTween(); - static final Animatable _rectAnimatableReverse = _rectTweenReverse.chain( + static final Animatable _rectAnimatableReverse = + _rectTweenReverse.chain( _curveReverse, ); static final RectTween _sheetRectTween = RectTween(); @@ -573,10 +583,12 @@ class _ContextMenuRoute extends PopupRoute { _curveReverse, ); static final Tween _sheetScaleTween = Tween(); - static final Animatable _sheetScaleAnimatable = _sheetScaleTween.chain( + static final Animatable _sheetScaleAnimatable = + _sheetScaleTween.chain( _curve, ); - static final Animatable _sheetScaleAnimatableReverse = _sheetScaleTween.chain( + static final Animatable _sheetScaleAnimatableReverse = + _sheetScaleTween.chain( _curveReverse, ); final Tween _opacityTween = Tween(begin: 0.0, end: 1.0); @@ -611,7 +623,8 @@ class _ContextMenuRoute extends PopupRoute { // Get the alignment for the _ContextMenuSheet's Transform.scale based on the // contextMenuLocation. - static AlignmentDirectional getSheetAlignment(_ContextMenuLocation contextMenuLocation) { + static AlignmentDirectional getSheetAlignment( + _ContextMenuLocation contextMenuLocation) { switch (contextMenuLocation) { case _ContextMenuLocation.center: return AlignmentDirectional.topCenter; @@ -623,17 +636,27 @@ class _ContextMenuRoute extends PopupRoute { } // The place to start the sheetRect animation from. - static Rect _getSheetRectBegin(Orientation? orientation, _ContextMenuLocation contextMenuLocation, Rect childRect, Rect sheetRect) { + static Rect _getSheetRectBegin( + Orientation? orientation, + _ContextMenuLocation contextMenuLocation, + Rect childRect, + Rect sheetRect) { switch (contextMenuLocation) { case _ContextMenuLocation.center: - final Offset target = orientation == Orientation.portrait ? childRect.bottomCenter : childRect.topCenter; + final Offset target = orientation == Orientation.portrait + ? childRect.bottomCenter + : childRect.topCenter; final Offset centered = target - Offset(sheetRect.width / 2, 0.0); return centered & sheetRect.size; case _ContextMenuLocation.right: - final Offset target = orientation == Orientation.portrait ? childRect.bottomRight : childRect.topRight; + final Offset target = orientation == Orientation.portrait + ? childRect.bottomRight + : childRect.topRight; return (target - Offset(sheetRect.width, 0.0)) & sheetRect.size; case _ContextMenuLocation.left: - final Offset target = orientation == Orientation.portrait ? childRect.bottomLeft : childRect.topLeft; + final Offset target = orientation == Orientation.portrait + ? childRect.bottomLeft + : childRect.topLeft; return target & sheetRect.size; } } @@ -651,7 +674,9 @@ class _ContextMenuRoute extends PopupRoute { // Take measurements on the child and _ContextMenuSheet and update the // animation tweens to match. void _updateTweenRects() { - final Rect childRect = _scale == null ? _getRect(_childGlobalKey) : _getScaledRect(_childGlobalKey, _scale!); + final Rect childRect = _scale == null + ? _getRect(_childGlobalKey) + : _getScaledRect(_childGlobalKey, _scale!); _rectTween.begin = _previousChildRect; _rectTween.end = childRect; @@ -725,7 +750,8 @@ class _ContextMenuRoute extends PopupRoute { } @override - Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { + Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { // This is usually used to build the "page", which is then passed to // buildTransitions as child, the idea being that buildTransitions will // animate the entire page into the scene. In the case of _ContextMenuRoute, @@ -735,7 +761,8 @@ class _ContextMenuRoute extends PopupRoute { } @override - Widget buildTransitions(BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { + Widget buildTransitions(BuildContext context, Animation animation, + Animation secondaryAnimation, Widget child) { return OrientationBuilder( builder: (BuildContext context, Orientation orientation) { _lastOrientation = orientation; @@ -744,9 +771,15 @@ class _ContextMenuRoute extends PopupRoute { // they're movable. if (!animation.isCompleted) { final bool reverse = animation.status == AnimationStatus.reverse; - final Rect rect = reverse ? _rectAnimatableReverse.evaluate(animation)! : _rectAnimatable.evaluate(animation)!; - final Rect sheetRect = reverse ? _sheetRectAnimatableReverse.evaluate(animation)! : _sheetRectAnimatable.evaluate(animation)!; - final double sheetScale = reverse ? _sheetScaleAnimatableReverse.evaluate(animation) : _sheetScaleAnimatable.evaluate(animation); + final Rect rect = reverse + ? _rectAnimatableReverse.evaluate(animation)! + : _rectAnimatable.evaluate(animation)!; + final Rect sheetRect = reverse + ? _sheetRectAnimatableReverse.evaluate(animation)! + : _sheetRectAnimatable.evaluate(animation)!; + final double sheetScale = reverse + ? _sheetScaleAnimatableReverse.evaluate(animation) + : _sheetScaleAnimatable.evaluate(animation); return Stack( children: [ Positioned.fromRect( @@ -818,7 +851,8 @@ class _ContextMenuRouteStatic extends StatefulWidget { _ContextMenuRouteStaticState createState() => _ContextMenuRouteStaticState(); } -class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with TickerProviderStateMixin { +class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> + with TickerProviderStateMixin { // The child is scaled down as it is dragged down until it hits this minimum // value. static const double _kMinScale = 0.8; @@ -838,7 +872,8 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T late Animation _sheetOpacityAnimation; // The scale of the child changes as a function of the distance it is dragged. - static double _getScale(Orientation orientation, double maxDragDistance, double dy) { + static double _getScale( + Orientation orientation, double maxDragDistance, double dy) { final double dyDirectional = dy <= 0.0 ? dy : -dy; return math.max( _kMinScale, @@ -859,11 +894,13 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T // If flung, animate a bit before handling the potential dismiss. if (details.velocity.pixelsPerSecond.dy.abs() >= kMinFlingVelocity) { final bool flingIsAway = details.velocity.pixelsPerSecond.dy > 0; - final double finalPosition = flingIsAway ? _moveAnimation.value.dy + 100.0 : 0.0; + final double finalPosition = + flingIsAway ? _moveAnimation.value.dy + 100.0 : 0.0; if (flingIsAway && _sheetController.status != AnimationStatus.forward) { _sheetController.forward(); - } else if (!flingIsAway && _sheetController.status != AnimationStatus.reverse) { + } else if (!flingIsAway && + _sheetController.status != AnimationStatus.reverse) { _sheetController.reverse(); } @@ -918,21 +955,30 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T widget.onDismiss!(context, _lastScale, _sheetOpacityAnimation.value); } - Alignment _getChildAlignment(Orientation orientation, _ContextMenuLocation contextMenuLocation) { + Alignment _getChildAlignment( + Orientation orientation, _ContextMenuLocation contextMenuLocation) { switch (contextMenuLocation) { case _ContextMenuLocation.center: - return orientation == Orientation.portrait ? Alignment.bottomCenter : Alignment.topRight; + return orientation == Orientation.portrait + ? Alignment.bottomCenter + : Alignment.topRight; case _ContextMenuLocation.right: - return orientation == Orientation.portrait ? Alignment.bottomCenter : Alignment.topLeft; + return orientation == Orientation.portrait + ? Alignment.bottomCenter + : Alignment.topLeft; case _ContextMenuLocation.left: - return orientation == Orientation.portrait ? Alignment.bottomCenter : Alignment.topRight; + return orientation == Orientation.portrait + ? Alignment.bottomCenter + : Alignment.topRight; } } void _setDragOffset(Offset dragOffset) { // Allow horizontal and negative vertical movement, but damp it. final double endX = _kPadding * dragOffset.dx / _kDamping; - final double endY = dragOffset.dy >= 0.0 ? dragOffset.dy : _kPadding * dragOffset.dy / _kDamping; + final double endY = dragOffset.dy >= 0.0 + ? dragOffset.dy + : _kPadding * dragOffset.dy / _kDamping; setState(() { _dragOffset = dragOffset; _moveAnimation = Tween( @@ -949,9 +995,13 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T ); // Fade the _ContextMenuSheet out or in, if needed. - if (_lastScale <= _kSheetScaleThreshold && _sheetController.status != AnimationStatus.forward && _sheetScaleAnimation.value != 0.0) { + if (_lastScale <= _kSheetScaleThreshold && + _sheetController.status != AnimationStatus.forward && + _sheetScaleAnimation.value != 0.0) { _sheetController.forward(); - } else if (_lastScale > _kSheetScaleThreshold && _sheetController.status != AnimationStatus.reverse && _sheetScaleAnimation.value != 1.0) { + } else if (_lastScale > _kSheetScaleThreshold && + _sheetController.status != AnimationStatus.reverse && + _sheetScaleAnimation.value != 1.0) { _sheetController.reverse(); } }); @@ -960,7 +1010,8 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T // The order and alignment of the _ContextMenuSheet and the child depend on // both the orientation of the screen as well as the position on the screen of // the original child. - List _getChildren(Orientation orientation, _ContextMenuLocation contextMenuLocation) { + List _getChildren( + Orientation orientation, _ContextMenuLocation contextMenuLocation) { final Expanded child = Expanded( child: Align( alignment: _getChildAlignment( @@ -995,7 +1046,9 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T case _ContextMenuLocation.center: return [child, spacer, sheet]; case _ContextMenuLocation.right: - return orientation == Orientation.portrait ? [child, spacer, sheet] : [sheet, spacer, child]; + return orientation == Orientation.portrait + ? [child, spacer, sheet] + : [sheet, spacer, child]; case _ContextMenuLocation.left: return [child, spacer, sheet]; } @@ -1004,7 +1057,8 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T // Build the animation for the _ContextMenuSheet. Widget _buildSheetAnimation(BuildContext context, Widget? child) { return Transform.scale( - alignment: _ContextMenuRoute.getSheetAlignment(widget.contextMenuLocation), + alignment: + _ContextMenuRoute.getSheetAlignment(widget.contextMenuLocation), scale: _sheetScaleAnimation.value, child: FadeTransition( opacity: _sheetOpacityAnimation, diff --git a/lib/base/ui/search_cell.dart b/lib/base/ui/search_cell.dart index bc4aacc..122627b 100644 --- a/lib/base/ui/search_cell.dart +++ b/lib/base/ui/search_cell.dart @@ -17,7 +17,6 @@ class SearchCell extends ConsumerStatefulWidget { } class _SearchCellState extends ConsumerState { - @override void initState() { super.initState(); @@ -35,9 +34,7 @@ class _SearchCellState extends ConsumerState { ), onSuffixTap: () { widget.controller.text = ""; - setState(() { - - }); + setState(() {}); }, controller: widget.controller, padding: const EdgeInsets.symmetric( diff --git a/lib/base/ui/source_code_view.dart b/lib/base/ui/source_code_view.dart index 4043cd6..4c41ab1 100644 --- a/lib/base/ui/source_code_view.dart +++ b/lib/base/ui/source_code_view.dart @@ -29,9 +29,8 @@ class SourceCodeView extends StatefulWidget { this.syntaxHighlighterStyle, }) : super(key: key); - String? get codeLink => codeLinkPrefix == null - ? null - : '$codeLinkPrefix/$filePath'; + String? get codeLink => + codeLinkPrefix == null ? null : '$codeLinkPrefix/$filePath'; @override _SourceCodeViewState createState() { diff --git a/lib/base/ui/syntax_highlighter.dart b/lib/base/ui/syntax_highlighter.dart index 101ca92..7c375dd 100644 --- a/lib/base/ui/syntax_highlighter.dart +++ b/lib/base/ui/syntax_highlighter.dart @@ -17,7 +17,10 @@ class SyntaxHighlighterStyle { this.constantStyle}); static SyntaxHighlighterStyle lightThemeStyle() => SyntaxHighlighterStyle( - baseStyle: const TextStyle(color: const Color(0xFF000000),height: 1,), + baseStyle: const TextStyle( + color: const Color(0xFF000000), + height: 1, + ), numberStyle: const TextStyle(color: const Color(0xFF1565C0)), commentStyle: const TextStyle(color: const Color(0xFF9E9E9E)), keywordStyle: const TextStyle(color: const Color(0xFF9C27B0)), diff --git a/lib/base/userinfo_viewmodel.dart b/lib/base/userinfo_viewmodel.dart index 66c0911..7b92fc9 100644 --- a/lib/base/userinfo_viewmodel.dart +++ b/lib/base/userinfo_viewmodel.dart @@ -26,7 +26,8 @@ class UserInfoViewModel { _useSecertLogined = SpUtil.getBool(spSecretLogined, defValue: false); _host = SpUtil.getString(spHost, defValue: ''); - List? tempList = jsonDecode(SpUtil.getString(spLoginHistory, defValue: '[]')); + List? tempList = + jsonDecode(SpUtil.getString(spLoginHistory, defValue: '[]')); if (tempList != null && tempList.isNotEmpty) { for (Map value in tempList) { @@ -40,7 +41,8 @@ class UserInfoViewModel { SpUtil.putString(spUserInfo, token); } - void updateUserName(String host, String userName, String password, bool secretLogin) { + void updateUserName( + String host, String userName, String password, bool secretLogin) { updateHost(host); _useSecretLogin(secretLogin); _userName = userName; @@ -93,7 +95,13 @@ class UserInfoViewModel { historyAccounts.removeWhere((element) => element.host == _host); - historyAccounts.insert(0, UserInfoBean(userName: _userName, password: _passWord, useSecretLogined: _useSecertLogined, host: _host)); + historyAccounts.insert( + 0, + UserInfoBean( + userName: _userName, + password: _passWord, + useSecretLogined: _useSecertLogined, + host: _host)); while (historyAccounts.length > 3) { historyAccounts.removeLast(); @@ -117,7 +125,8 @@ class UserInfoBean { bool useSecretLogined = false; String? host; - UserInfoBean({this.userName, this.password, this.useSecretLogined = false, this.host}); + UserInfoBean( + {this.userName, this.password, this.useSecretLogined = false, this.host}); UserInfoBean.fromJson(Map json) { userName = json['userName']; diff --git a/lib/json.jc.dart b/lib/json.jc.dart index cf338fb..9c82c48 100644 --- a/lib/json.jc.dart +++ b/lib/json.jc.dart @@ -11,10 +11,8 @@ import 'package:qinglong_app/module/others/scripts/script_bean.dart'; import 'package:qinglong_app/module/others/task_log/task_log_bean.dart'; import 'package:qinglong_app/module/task/task_bean.dart'; - class JsonConversion$Json { - - static M fromJson(dynamic json) { + static M fromJson(dynamic json) { if (json is List) { return _getListChildType(json); } else { @@ -23,93 +21,104 @@ class JsonConversion$Json { } static M _fromJsonSingle(dynamic json) { - String type = M.toString(); - if(type == (ConfigBean).toString()){ - return ConfigBean.jsonConversion(json) as M; + if (type == (ConfigBean).toString()) { + return ConfigBean.jsonConversion(json) as M; } - - if(type == (EnvBean).toString()){ - return EnvBean.jsonConversion(json) as M; + + if (type == (EnvBean).toString()) { + return EnvBean.jsonConversion(json) as M; } - - if(type == (SystemBean).toString()){ - return SystemBean.jsonConversion(json) as M; + + if (type == (SystemBean).toString()) { + return SystemBean.jsonConversion(json) as M; } - - if(type == (LoginBean).toString()){ - return LoginBean.jsonConversion(json) as M; + + if (type == (LoginBean).toString()) { + return LoginBean.jsonConversion(json) as M; } - - if(type == (UserBean).toString()){ - return UserBean.jsonConversion(json) as M; + + if (type == (UserBean).toString()) { + return UserBean.jsonConversion(json) as M; } - - if(type == (DependencyBean).toString()){ - return DependencyBean.jsonConversion(json) as M; + + if (type == (DependencyBean).toString()) { + return DependencyBean.jsonConversion(json) as M; } - - if(type == (LoginLogBean).toString()){ - return LoginLogBean.jsonConversion(json) as M; + + if (type == (LoginLogBean).toString()) { + return LoginLogBean.jsonConversion(json) as M; } - - if(type == (ScriptBean).toString()){ - return ScriptBean.jsonConversion(json) as M; + + if (type == (ScriptBean).toString()) { + return ScriptBean.jsonConversion(json) as M; } - - if(type == (TaskLogBean).toString()){ - return TaskLogBean.jsonConversion(json) as M; + + if (type == (TaskLogBean).toString()) { + return TaskLogBean.jsonConversion(json) as M; } - - if(type == (TaskBean).toString()){ - return TaskBean.jsonConversion(json) as M; + + if (type == (TaskBean).toString()) { + return TaskBean.jsonConversion(json) as M; } - + throw Exception("not found"); } static M _getListChildType(List data) { - if([] is M){ - return data.map((e) => ConfigBean.jsonConversion(e)).toList() as M; + if ([] is M) { + return data.map((e) => ConfigBean.jsonConversion(e)).toList() + as M; } - - if([] is M){ + + if ([] is M) { return data.map((e) => EnvBean.jsonConversion(e)).toList() as M; } - - if([] is M){ - return data.map((e) => SystemBean.jsonConversion(e)).toList() as M; + + if ([] is M) { + return data.map((e) => SystemBean.jsonConversion(e)).toList() + as M; } - - if([] is M){ - return data.map((e) => LoginBean.jsonConversion(e)).toList() as M; + + if ([] is M) { + return data.map((e) => LoginBean.jsonConversion(e)).toList() + as M; } - - if([] is M){ - return data.map((e) => UserBean.jsonConversion(e)).toList() as M; + + if ([] is M) { + return data.map((e) => UserBean.jsonConversion(e)).toList() + as M; } - - if([] is M){ - return data.map((e) => DependencyBean.jsonConversion(e)).toList() as M; + + if ([] is M) { + return data + .map((e) => DependencyBean.jsonConversion(e)) + .toList() as M; } - - if([] is M){ - return data.map((e) => LoginLogBean.jsonConversion(e)).toList() as M; + + if ([] is M) { + return data + .map((e) => LoginLogBean.jsonConversion(e)) + .toList() as M; } - - if([] is M){ - return data.map((e) => ScriptBean.jsonConversion(e)).toList() as M; + + if ([] is M) { + return data.map((e) => ScriptBean.jsonConversion(e)).toList() + as M; } - - if([] is M){ - return data.map((e) => TaskLogBean.jsonConversion(e)).toList() as M; + + if ([] is M) { + return data + .map((e) => TaskLogBean.jsonConversion(e)) + .toList() as M; } - - if([] is M){ - return data.map((e) => TaskBean.jsonConversion(e)).toList() as M; + + if ([] is M) { + return data.map((e) => TaskBean.jsonConversion(e)).toList() + as M; } - + throw Exception("not found"); } } diff --git a/lib/main.dart b/lib/main.dart index ef71de6..c24a918 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -41,7 +41,8 @@ void main() async { ), ); if (Platform.isAndroid) { - SystemUiOverlayStyle style = const SystemUiOverlayStyle(statusBarColor: Colors.transparent); + SystemUiOverlayStyle style = + const SystemUiOverlayStyle(statusBarColor: Colors.transparent); SystemChrome.setSystemUIOverlayStyle(style); } } @@ -62,7 +63,8 @@ class QlAppState extends ConsumerState { FocusScope.of(context).requestFocus(FocusNode()); }, child: MediaQuery( - data: MediaQueryData.fromWindow(WidgetsBinding.instance.window).copyWith( + data: + MediaQueryData.fromWindow(WidgetsBinding.instance.window).copyWith( textScaleFactor: 1, ), child: MaterialApp( @@ -87,7 +89,9 @@ class QlAppState extends ConsumerState { if (!kReleaseMode) { showDebugBtn(context); } - return getIt().isLogined() ? const HomePage() : const LoginPage(); + return getIt().isLogined() + ? const HomePage() + : const LoginPage(); }, ), // home: LoginPage(), diff --git a/lib/module/change_account_page.dart b/lib/module/change_account_page.dart index 77343c6..87474a1 100644 --- a/lib/module/change_account_page.dart +++ b/lib/module/change_account_page.dart @@ -64,13 +64,17 @@ class _ChangeAccountPageState extends ConsumerState { shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { - if (index == getIt().historyAccounts.length) { + if (index == + getIt().historyAccounts.length) { return addAccount(); } return ClipRRect( borderRadius: BorderRadius.circular(10), child: Container( - color: ref.watch(themeProvider).themeColor.settingBordorColor(), + color: ref + .watch(themeProvider) + .themeColor + .settingBordorColor(), child: buildCell(index), ), ); @@ -80,7 +84,8 @@ class _ChangeAccountPageState extends ConsumerState { height: 10, ); }, - itemCount: getIt().historyAccounts.length + 1), + itemCount: + getIt().historyAccounts.length + 1), ), ], ), @@ -108,31 +113,34 @@ class _ChangeAccountPageState extends ConsumerState { ), trailing: index == 0 ? Container( - padding: const EdgeInsets.symmetric( - horizontal: 5, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - border: Border.all(color: ref.watch(themeProvider).primaryColor, width: 1), - ), - child: Text( - "已登录", - style: TextStyle(color: ref.watch(themeProvider).primaryColor, fontSize: 12), - ), - ) + padding: const EdgeInsets.symmetric( + horizontal: 5, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + border: Border.all( + color: ref.watch(themeProvider).primaryColor, width: 1), + ), + child: Text( + "已登录", + style: TextStyle( + color: ref.watch(themeProvider).primaryColor, fontSize: 12), + ), + ) : (isLoginingHost.isNotEmpty - ? SizedBox( - width: 15, - height: 15, - child: CircularProgressIndicator( - strokeWidth: 2, - color: ref.watch(themeProvider).primaryColor, - ), - ) - : const SizedBox.shrink()), + ? SizedBox( + width: 15, + height: 15, + child: CircularProgressIndicator( + strokeWidth: 2, + color: ref.watch(themeProvider).primaryColor, + ), + ) + : const SizedBox.shrink()), ); - if (getIt().historyAccounts[index].host == getIt().host) { + if (getIt().historyAccounts[index].host == + getIt().host) { return child; } @@ -146,7 +154,8 @@ class _ChangeAccountPageState extends ConsumerState { backgroundColor: Colors.red, flex: 1, onPressed: (_) { - getIt().removeHistoryAccount(getIt().historyAccounts[index].host); + getIt().removeHistoryAccount( + getIt().historyAccounts[index].host); setState(() {}); }, foregroundColor: Colors.white, @@ -181,7 +190,8 @@ class _ChangeAccountPageState extends ConsumerState { void dealLoginResponse(int response) { if (response == LoginHelper.success) { - Navigator.of(context).pushNamedAndRemoveUntil(Routes.routeHomePage, (_) => false); + Navigator.of(context) + .pushNamedAndRemoveUntil(Routes.routeHomePage, (_) => false); } else if (response == LoginHelper.failed) { loginFailed(); } else { @@ -201,58 +211,58 @@ class _ChangeAccountPageState extends ConsumerState { showCupertinoDialog( context: context, builder: (_) => CupertinoAlertDialog( - title: const Text("两步验证"), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Material( - color: Colors.transparent, - child: TextField( - onChanged: (value) { - twoFact = value; - }, - maxLines: 1, - keyboardType: TextInputType.number, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入code", + title: const Text("两步验证"), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Material( + color: Colors.transparent, + child: TextField( + onChanged: (value) { + twoFact = value; + }, + maxLines: 1, + keyboardType: TextInputType.number, + decoration: const InputDecoration( + contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), + hintText: "请输入code", + ), + autofocus: true, + ), ), - autofocus: true, - ), + ], ), - ], - ), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), + actions: [ + CupertinoDialogAction( + child: const Text( + "取消", + style: TextStyle( + color: Color(0xff999999), + ), + ), + onPressed: () { + Navigator.of(context).pop(); + }, ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, + CupertinoDialogAction( + child: Text( + "确定", + style: TextStyle( + color: ref.watch(themeProvider).primaryColor, + ), + ), + onPressed: () async { + Navigator.of(context).pop(true); + if (helper != null) { + var response = await helper!.loginTwice(twoFact); + dealLoginResponse(response); + } else { + "状态异常".toast(); + } + }, ), - ), - onPressed: () async { - Navigator.of(context).pop(true); - if (helper != null) { - var response = await helper!.loginTwice(twoFact); - dealLoginResponse(response); - } else { - "状态异常".toast(); - } - }, - ), - ], - )).then((value) { + ], + )).then((value) { if (value == null) { isLoginingHost = ""; setState(() {}); @@ -266,7 +276,7 @@ class _ChangeAccountPageState extends ConsumerState { onTap: () { Navigator.of(context).pushNamedAndRemoveUntil( Routes.routeLogin, - (_) => false, + (_) => false, arguments: true, ); }, diff --git a/lib/module/config/config_edit_page.dart b/lib/module/config/config_edit_page.dart index 82f54e0..bfad5f8 100644 --- a/lib/module/config/config_edit_page.dart +++ b/lib/module/config/config_edit_page.dart @@ -47,8 +47,8 @@ class _ConfigEditPageState extends ConsumerState { }); } - Future notifyICloud(BuildContext context, String? title, String? content) async { - } + Future notifyICloud( + BuildContext context, String? title, String? content) async {} @override Widget build(BuildContext context) { @@ -60,7 +60,8 @@ class _ConfigEditPageState extends ConsumerState { }, theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), stringMap: { - "export": const TextStyle(fontWeight: FontWeight.normal, color: Color(0xff6B2375)), + "export": const TextStyle( + fontWeight: FontWeight.normal, color: Color(0xff6B2375)), }, ); return Scaffold( @@ -122,10 +123,10 @@ class _ConfigEditPageState extends ConsumerState { ...operateList .map( (e) => PopupMenuItem( - child: Text(e), - value: e, - ), - ) + child: Text(e), + value: e, + ), + ) .toList(), ], child: const Center( @@ -137,7 +138,8 @@ class _ConfigEditPageState extends ConsumerState { ), InkWell( onTap: () async { - HttpResponse response = await Api.saveFile(widget.title, result); + HttpResponse response = + await Api.saveFile(widget.title, result); await notifyICloud(context, widget.title, result); if (response.success) { "提交成功".toast(); @@ -226,7 +228,8 @@ class _ConfigEditPageState extends ConsumerState { } } catch (e) {} - TextEditingController controller = TextEditingController(text: defaultValue.replaceAll("\"", "").replaceAll("'", "")); + TextEditingController controller = TextEditingController( + text: defaultValue.replaceAll("\"", "").replaceAll("'", "")); showCupertinoDialog( useRootNavigator: false, context: context, diff --git a/lib/module/config/config_page.dart b/lib/module/config/config_page.dart index 9a9e8cc..e6b38ee 100644 --- a/lib/module/config/config_page.dart +++ b/lib/module/config/config_page.dart @@ -24,7 +24,8 @@ class ConfigPage extends StatefulWidget { ConfigPageState createState() => ConfigPageState(); } -class ConfigPageState extends State with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin { +class ConfigPageState extends State + with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin { int _initIndex = 0; BuildContext? childContext; @@ -89,8 +90,14 @@ class ConfigPageState extends State with SingleTickerProviderStateMi void editMe(WidgetRef ref) { if (childContext == null) return; navigatorState.currentState?.pushNamed(Routes.routeConfigEdit, arguments: { - "title": ref.read(configProvider).list[DefaultTabController.of(childContext!)?.index ?? 0].title, - "content": ref.read(configProvider).content[ref.read(configProvider).list[DefaultTabController.of(childContext!)?.index ?? 0].title] + "title": ref + .read(configProvider) + .list[DefaultTabController.of(childContext!)?.index ?? 0] + .title, + "content": ref.read(configProvider).content[ref + .read(configProvider) + .list[DefaultTabController.of(childContext!)?.index ?? 0] + .title] }).then((value) async { if (value != null && (value as String).isNotEmpty) { await ref.read(configProvider).loadContent(value); @@ -115,7 +122,8 @@ class CodeWidget extends ConsumerStatefulWidget { ConsumerState createState() => _CodeWidgetState(); } -class _CodeWidgetState extends ConsumerState with AutomaticKeepAliveClientMixin { +class _CodeWidgetState extends ConsumerState + with AutomaticKeepAliveClientMixin { CodeController? _codeController; @override @@ -143,7 +151,8 @@ class _CodeWidgetState extends ConsumerState with AutomaticKeepAlive }, theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), stringMap: { - "export": const TextStyle(fontWeight: FontWeight.normal, color: Color(0xff6B2375)), + "export": const TextStyle( + fontWeight: FontWeight.normal, color: Color(0xff6B2375)), }, ); return SafeArea( diff --git a/lib/module/env/add_env_page.dart b/lib/module/env/add_env_page.dart index 70e0ff3..cedebfc 100644 --- a/lib/module/env/add_env_page.dart +++ b/lib/module/env/add_env_page.dart @@ -186,8 +186,12 @@ class _AddEnvPageState extends ConsumerState { envBean.value = _valueController.text; envBean.remarks = _remarkController.text; HttpResponse response = await Api.addEnv( - _nameController.text, _valueController.text, _remarkController.text, - id: envBean.id,nId: envBean.nId,); + _nameController.text, + _valueController.text, + _remarkController.text, + id: envBean.id, + nId: envBean.nId, + ); if (response.success) { (envBean.sId == null) ? "新增成功" : "修改成功".toast(); diff --git a/lib/module/env/env_bean.dart b/lib/module/env/env_bean.dart index d149410..c5f8a86 100644 --- a/lib/module/env/env_bean.dart +++ b/lib/module/env/env_bean.dart @@ -12,7 +12,14 @@ class EnvBean { String? name; String? remarks; - EnvBean({this.value, this.sId, this.created, this.status, this.timestamp, this.name, this.remarks}); + EnvBean( + {this.value, + this.sId, + this.created, + this.status, + this.timestamp, + this.name, + this.remarks}); get nId => _id; @@ -20,7 +27,9 @@ class EnvBean { value = json['value']; id = json['id']; _id = json['_id']; - sId = json.containsKey('_id') ? json['_id'].toString() : (json.containsKey('id') ? json['id'].toString() : ""); + sId = json.containsKey('_id') + ? json['_id'].toString() + : (json.containsKey('id') ? json['id'].toString() : ""); created = int.tryParse(json['created'].toString()); status = json['status']; timestamp = json['timestamp']; diff --git a/lib/module/env/env_detail_page.dart b/lib/module/env/env_detail_page.dart index 28a983f..83a3680 100644 --- a/lib/module/env/env_detail_page.dart +++ b/lib/module/env/env_detail_page.dart @@ -36,7 +36,8 @@ class _TaskDetailPageState extends ConsumerState { behavior: HitTestBehavior.opaque, onTap: () { Navigator.of(context).pop(); - Navigator.of(context).pushNamed(Routes.routeAddEnv, arguments: widget.envBean); + Navigator.of(context) + .pushNamed(Routes.routeAddEnv, arguments: widget.envBean); }, child: Container( padding: const EdgeInsets.symmetric( @@ -225,7 +226,9 @@ class _TaskDetailPageState extends ConsumerState { } void enableTask() async { - await ref.read(envProvider).enableEnv(widget.envBean.sId!, widget.envBean.status!); + await ref + .read(envProvider) + .enableEnv(widget.envBean.sId!, widget.envBean.status!); setState(() {}); } @@ -322,14 +325,16 @@ class EnvDetailCell extends ConsumerWidget { } }, style: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), + color: + ref.watch(themeProvider).themeColor.descColor(), fontSize: 14, ), ), ), ) : Expanded( - child: Align(alignment: Alignment.centerRight, child: icon!), + child: + Align(alignment: Alignment.centerRight, child: icon!), ), ], ), diff --git a/lib/module/env/env_page.dart b/lib/module/env/env_page.dart index aee9752..2303f72 100644 --- a/lib/module/env/env_page.dart +++ b/lib/module/env/env_page.dart @@ -83,7 +83,8 @@ class _EnvPageState extends State { ], ) : ReorderableListView( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, header: searchCell(context, ref), onReorder: (int oldIndex, int newIndex) { if (list.length != model.list.length) { @@ -97,9 +98,11 @@ class _EnvPageState extends State { if (newIndex > oldIndex) { newIndex -= 1; } - final EnvBean item = model.list.removeAt(oldIndex); + final EnvBean item = + model.list.removeAt(oldIndex); model.list.insert(newIndex, item); - model.update(item.sId ?? "", newIndex, oldIndex); + model.update( + item.sId ?? "", newIndex, oldIndex); }, ); }, @@ -145,7 +148,9 @@ class _EnvPageState extends State { child: Text( EnvViewModel.allStr, style: TextStyle( - color: currentState == EnvViewModel.allStr ? ref.watch(themeProvider).primaryColor : ref.watch(themeProvider).themeColor.titleColor(), + color: currentState == EnvViewModel.allStr + ? ref.watch(themeProvider).primaryColor + : ref.watch(themeProvider).themeColor.titleColor(), fontSize: 14, ), ), @@ -155,7 +160,9 @@ class _EnvPageState extends State { child: Text( EnvViewModel.enabledStr, style: TextStyle( - color: currentState == EnvViewModel.enabledStr ? ref.watch(themeProvider).primaryColor : ref.watch(themeProvider).themeColor.titleColor(), + color: currentState == EnvViewModel.enabledStr + ? ref.watch(themeProvider).primaryColor + : ref.watch(themeProvider).themeColor.titleColor(), fontSize: 14, ), ), @@ -165,8 +172,9 @@ class _EnvPageState extends State { child: Text( EnvViewModel.disabledStr, style: TextStyle( - color: - currentState == EnvViewModel.disabledStr ? ref.watch(themeProvider).primaryColor : ref.watch(themeProvider).themeColor.titleColor(), + color: currentState == EnvViewModel.disabledStr + ? ref.watch(themeProvider).primaryColor + : ref.watch(themeProvider).themeColor.titleColor(), fontSize: 14, ), ), @@ -199,7 +207,8 @@ class EnvItemCell extends StatelessWidget { final int index; final WidgetRef ref; - const EnvItemCell(this.bean, this.index, this.ref, {Key? key}) : super(key: key); + const EnvItemCell(this.bean, this.index, this.ref, {Key? key}) + : super(key: key); @override Widget build(BuildContext context) { @@ -212,7 +221,8 @@ class EnvItemCell extends StatelessWidget { SlidableAction( backgroundColor: const Color(0xff5D5E70), onPressed: (_) { - Navigator.of(context).pushNamed(Routes.routeAddEnv, arguments: bean); + Navigator.of(context) + .pushNamed(Routes.routeAddEnv, arguments: bean); }, foregroundColor: Colors.white, icon: CupertinoIcons.pencil_outline, @@ -223,7 +233,9 @@ class EnvItemCell extends StatelessWidget { enableEnv(context); }, foregroundColor: Colors.white, - icon: bean.status == 0 ? Icons.dnd_forwardslash : Icons.check_circle_outline_sharp, + icon: bean.status == 0 + ? Icons.dnd_forwardslash + : Icons.check_circle_outline_sharp, ), SlidableAction( backgroundColor: const Color(0xffEA4D3E), @@ -245,7 +257,8 @@ class EnvItemCell extends StatelessWidget { color: ref.watch(themeProvider).themeColor.settingBgColor(), child: InkWell( onTap: () { - Navigator.of(context).pushNamed(Routes.routeEnvDetail, arguments: bean); + Navigator.of(context) + .pushNamed(Routes.routeEnvDetail, arguments: bean); }, child: Container( padding: const EdgeInsets.symmetric( @@ -272,13 +285,22 @@ class EnvItemCell extends StatelessWidget { horizontal: 5, ), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(3), - border: Border.all(color: ref.watch(themeProvider).themeColor.descColor(), width: 1), + borderRadius: + BorderRadius.circular(3), + border: Border.all( + color: ref + .watch(themeProvider) + .themeColor + .descColor(), + width: 1), ), child: Text( "${getIndexByIndex(context, index)}", style: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), fontSize: 12, ), ), @@ -299,7 +321,10 @@ class EnvItemCell extends StatelessWidget { maxLines: 1, style: TextStyle( overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -315,7 +340,8 @@ class EnvItemCell extends StatelessWidget { ), ), child: Visibility( - visible: bean.remarks != null && bean.remarks!.isNotEmpty, + visible: bean.remarks != null && + bean.remarks!.isNotEmpty, child: Material( color: Colors.transparent, child: Text( @@ -324,7 +350,10 @@ class EnvItemCell extends StatelessWidget { style: TextStyle( height: 1, overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), fontSize: 12, ), ), @@ -358,7 +387,10 @@ class EnvItemCell extends StatelessWidget { maxLines: 1, style: TextStyle( overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), fontSize: 12, ), ), @@ -375,7 +407,8 @@ class EnvItemCell extends StatelessWidget { maxLines: 1, style: TextStyle( overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), + color: + ref.watch(themeProvider).themeColor.descColor(), fontSize: 12, ), ), diff --git a/lib/module/env/env_viewmodel.dart b/lib/module/env/env_viewmodel.dart index 50ab7d9..05cfbc9 100644 --- a/lib/module/env/env_viewmodel.dart +++ b/lib/module/env/env_viewmodel.dart @@ -15,7 +15,6 @@ class EnvViewModel extends BaseViewModel { List disabledList = []; List enabledList = []; - Future loadData([isLoading = true]) async { if (isLoading && list.isEmpty) { loading(notify: true); @@ -23,12 +22,12 @@ class EnvViewModel extends BaseViewModel { HttpResponse> result = await Api.envs(""); - if (result.success && result.bean != null) { list.clear(); list.addAll(result.bean!); disabledList.clear(); - disabledList.addAll(list.where((element) => element.status == 1).toList()); + disabledList + .addAll(list.where((element) => element.status == 1).toList()); enabledList.clear(); enabledList.addAll(list.where((element) => element.status == 0).toList()); success(); diff --git a/lib/module/login/login_page.dart b/lib/module/login/login_page.dart index 37042b3..5afdb7c 100644 --- a/lib/module/login/login_page.dart +++ b/lib/module/login/login_page.dart @@ -44,7 +44,8 @@ class _LoginPageState extends ConsumerState { if (!widget.doNotLoadLocalData) { _hostController.text = getIt().host ?? ""; useSecretLogin = getIt().useSecretLogined; - if (getIt().userName != null && getIt().userName!.isNotEmpty) { + if (getIt().userName != null && + getIt().userName!.isNotEmpty) { if (getIt().useSecretLogined) { _cIdController.text = getIt().userName!; } else { @@ -54,7 +55,8 @@ class _LoginPageState extends ConsumerState { } else { rememberPassword = false; } - if (getIt().passWord != null && getIt().passWord!.isNotEmpty) { + if (getIt().passWord != null && + getIt().passWord!.isNotEmpty) { if (getIt().useSecretLogined) { _cSecretController.text = getIt().passWord!; } else { @@ -76,7 +78,9 @@ class _LoginPageState extends ConsumerState { Widget build(BuildContext context) { return Scaffold( body: AnnotatedRegion( - value: ref.watch(themeProvider).darkMode == true ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark, + value: ref.watch(themeProvider).darkMode == true + ? SystemUiOverlayStyle.light + : SystemUiOverlayStyle.dark, child: ColoredBox( color: ref.watch(themeProvider).themeColor.settingBgColor(), child: SingleChildScrollView( @@ -105,7 +109,10 @@ class _LoginPageState extends ConsumerState { style: TextStyle( fontSize: 26, fontWeight: FontWeight.bold, - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), ), ), ), @@ -115,7 +122,9 @@ class _LoginPageState extends ConsumerState { if (debugBtnIsShow()) { dismissDebugBtn(); } else { - showDebugBtn(context, btnColor: ref.watch(themeProvider).primaryColor); + showDebugBtn(context, + btnColor: + ref.watch(themeProvider).primaryColor); } WidgetsBinding.instance.endOfFrame; }, @@ -158,7 +167,10 @@ class _LoginPageState extends ConsumerState { hintText: "http://1.1.1.1:5700", hintStyle: TextStyle( fontSize: 16, - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), ), ), autofocus: false, @@ -216,7 +228,10 @@ class _LoginPageState extends ConsumerState { hintText: "请输入账户", hintStyle: TextStyle( fontSize: 16, - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), ), ), autofocus: false, @@ -260,7 +275,10 @@ class _LoginPageState extends ConsumerState { hintText: "请输入密码", hintStyle: TextStyle( fontSize: 16, - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), ), ), autofocus: false, @@ -310,7 +328,10 @@ class _LoginPageState extends ConsumerState { hintText: "请输入client_id", hintStyle: TextStyle( fontSize: 16, - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), ), ), autofocus: false, @@ -354,7 +375,10 @@ class _LoginPageState extends ConsumerState { hintText: "请输入client_secret", hintStyle: TextStyle( fontSize: 16, - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), ), ), autofocus: false, @@ -399,7 +423,8 @@ class _LoginPageState extends ConsumerState { GestureDetector( onTap: () { cardKey.currentState?.toggleCard(); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + WidgetsBinding.instance + .addPostFrameCallback((timeStamp) { setState(() {}); }); }, @@ -421,7 +446,8 @@ class _LoginPageState extends ConsumerState { height: 30, ), Shake( - preferences: const AnimationPreferences(autoPlay: AnimationPlayStates.None), + preferences: const AnimationPreferences( + autoPlay: AnimationPlayStates.None), key: loginKey, child: Center( child: Container( @@ -469,9 +495,11 @@ class _LoginPageState extends ConsumerState { Http.pushedLoginPage = false; Utils.hideKeyBoard(context); if (loginByUserName()) { - login(_userNameController.text, _passwordController.text); + login(_userNameController.text, + _passwordController.text); } else { - login(_cIdController.text, _cSecretController.text); + login(_cIdController.text, + _cSecretController.text); } }, ); @@ -498,7 +526,8 @@ class _LoginPageState extends ConsumerState { onSelected: (UserInfoBean result) { selected(result); }, - itemBuilder: (BuildContext context) => >[ + itemBuilder: (BuildContext context) => + >[ ...getIt() .historyAccounts .map( @@ -554,7 +583,8 @@ class _LoginPageState extends ConsumerState { isLoading = true; setState(() {}); - helper = LoginHelper(useSecretLogin, _hostController.text, userName, password, rememberPassword); + helper = LoginHelper(useSecretLogin, _hostController.text, userName, + password, rememberPassword); var response = await helper!.login(); dealLoginResponse(response); } @@ -581,9 +611,11 @@ class _LoginPageState extends ConsumerState { if (_hostController.text.isEmpty) return false; if (!loginByUserName()) { - return _cIdController.text.isNotEmpty && _cSecretController.text.isNotEmpty; + return _cIdController.text.isNotEmpty && + _cSecretController.text.isNotEmpty; } else { - return _userNameController.text.isNotEmpty && _passwordController.text.isNotEmpty; + return _userNameController.text.isNotEmpty && + _passwordController.text.isNotEmpty; } } diff --git a/lib/module/login/user_bean.dart b/lib/module/login/user_bean.dart index 4ace31f..e3d2a83 100644 --- a/lib/module/login/user_bean.dart +++ b/lib/module/login/user_bean.dart @@ -19,6 +19,7 @@ class UserBean { data['twoFactorActivated'] = this.twoFactorActivated; return data; } + static UserBean jsonConversion(Map json) { return UserBean.fromJson(json); } diff --git a/lib/module/others/about_page.dart b/lib/module/others/about_page.dart index 78d852e..a6d4a51 100644 --- a/lib/module/others/about_page.dart +++ b/lib/module/others/about_page.dart @@ -23,7 +23,6 @@ class _AboutPageState extends ConsumerState { void initState() { super.initState(); getInfo(); - } @override @@ -88,7 +87,8 @@ class _AboutPageState extends ConsumerState { const Spacer(), GestureDetector( onTap: () { - _launchURL("https://github.com/qinglong-app/qinglong_app/releases"); + _launchURL( + "https://github.com/qinglong-app/qinglong_app/releases"); }, child: Text( "版本更新", diff --git a/lib/module/others/dependencies/dependency_page.dart b/lib/module/others/dependencies/dependency_page.dart index 150c2f8..e2bf41e 100644 --- a/lib/module/others/dependencies/dependency_page.dart +++ b/lib/module/others/dependencies/dependency_page.dart @@ -21,7 +21,8 @@ class DependencyPage extends StatefulWidget { _DependcyPageState createState() => _DependcyPageState(); } -class _DependcyPageState extends State with TickerProviderStateMixin { +class _DependcyPageState extends State + with TickerProviderStateMixin { List types = []; TabController? _tabController; @@ -125,7 +126,9 @@ class _DependcyPageState extends State with TickerProviderStateM itemCount: list.length, ), onRefresh: () { - return model.loadData(types[_tabController!.index].name.toLowerCase(), false); + return model.loadData( + types[_tabController!.index].name.toLowerCase(), + false); }, ); }, @@ -222,7 +225,10 @@ class DependencyCell extends ConsumerWidget { maxLines: 1, style: TextStyle( overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 18, ), ), @@ -255,11 +261,16 @@ class DependencyCell extends ConsumerWidget { child: Material( color: Colors.transparent, child: Text( - (bean.created == null || bean.created == 0) ? "-" : Utils.formatMessageTime(bean.created!), + (bean.created == null || bean.created == 0) + ? "-" + : Utils.formatMessageTime(bean.created!), maxLines: 1, style: TextStyle( overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), + color: ref + .watch(themeProvider) + .themeColor + .descColor(), fontSize: 12, ), ), @@ -357,7 +368,9 @@ class DependencyCell extends ConsumerWidget { ), onPressed: () { Navigator.of(context).pop(); - ref.read(dependencyProvider).del(type.name.toLowerCase(), sId ?? ""); + ref + .read(dependencyProvider) + .del(type.name.toLowerCase(), sId ?? ""); }, ), ], diff --git a/lib/module/others/dependencies/dependency_viewmodel.dart b/lib/module/others/dependencies/dependency_viewmodel.dart index e96e187..aa70dc2 100644 --- a/lib/module/others/dependencies/dependency_viewmodel.dart +++ b/lib/module/others/dependencies/dependency_viewmodel.dart @@ -15,7 +15,10 @@ class DependencyViewModel extends BaseViewModel { List linuxList = []; Future loadData(String type, [bool showLoading = true]) async { - if (showLoading && ((type == "nodejs" && nodeJsList.isEmpty) || (type == "python3" && python3List.isEmpty) || (type == "linux" && linuxList.isEmpty))) { + if (showLoading && + ((type == "nodejs" && nodeJsList.isEmpty) || + (type == "python3" && python3List.isEmpty) || + (type == "linux" && linuxList.isEmpty))) { loading(notify: true); } diff --git a/lib/module/others/login_log/login_log_page.dart b/lib/module/others/login_log/login_log_page.dart index bc4afc9..ab51a05 100644 --- a/lib/module/others/login_log/login_log_page.dart +++ b/lib/module/others/login_log/login_log_page.dart @@ -37,99 +37,98 @@ class _LoginLogPageState extends ConsumerState ), body: list.isEmpty ? const Center( - child: CupertinoActivityIndicator(), - ) + child: CupertinoActivityIndicator(), + ) : ListView.separated( - itemBuilder: (context, index) { - LoginLogBean item = list[index]; + itemBuilder: (context, index) { + LoginLogBean item = list[index]; - return Row( - children: [ - const SizedBox( - width: 15, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 10, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "${item.address}", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 14, - ), - ), - const SizedBox( - width: 5, - ), - Padding( - padding: const EdgeInsets.only( - top: 2, - ), - child: Image.asset( - item.status == 0 - ? "assets/images/icon_success.png" - : "assets/images/icon_fail.png", - width: 30, - fit: BoxFit.cover, - ), - ), - ], - ), - const SizedBox( - height: 10, - ), - SelectableText( - "${item.ip}", - selectionWidthStyle: BoxWidthStyle.max, - selectionHeightStyle: BoxHeightStyle.max, - style: TextStyle( - color: - ref.watch(themeProvider).themeColor.descColor(), - fontSize: 14, + return Row( + children: [ + const SizedBox( + width: 15, ), - ), - const SizedBox( - height: 10, - ), - ], - ), - const Spacer(), - Text( - Utils.formatMessageTime(item.timestamp ?? 0), - style: TextStyle( - fontSize: 12, - color: ref.watch(themeProvider).themeColor.descColor(), - ), - ), - const SizedBox( - width: 15, - ), - ], - ); - }, - itemCount: list.length, - separatorBuilder: (BuildContext context, int index) { - return const Divider( - indent: 15, - height: 1, - ); - }, - ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 10, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "${item.address}", + style: TextStyle( + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), + fontSize: 14, + ), + ), + const SizedBox( + width: 5, + ), + Padding( + padding: const EdgeInsets.only( + top: 2, + ), + child: Image.asset( + item.status == 0 + ? "assets/images/icon_success.png" + : "assets/images/icon_fail.png", + width: 30, + fit: BoxFit.cover, + ), + ), + ], + ), + const SizedBox( + height: 10, + ), + SelectableText( + "${item.ip}", + selectionWidthStyle: BoxWidthStyle.max, + selectionHeightStyle: BoxHeightStyle.max, + style: TextStyle( + color: + ref.watch(themeProvider).themeColor.descColor(), + fontSize: 14, + ), + ), + const SizedBox( + height: 10, + ), + ], + ), + const Spacer(), + Text( + Utils.formatMessageTime(item.timestamp ?? 0), + style: TextStyle( + fontSize: 12, + color: ref.watch(themeProvider).themeColor.descColor(), + ), + ), + const SizedBox( + width: 15, + ), + ], + ); + }, + itemCount: list.length, + separatorBuilder: (BuildContext context, int index) { + return const Divider( + indent: 15, + height: 1, + ); + }, + ), ); } Future loadData() async { - HttpResponse> response = - await Api.loginLog(); + HttpResponse> response = await Api.loginLog(); if (response.success) { if (response.bean == null || response.bean!.isEmpty) { diff --git a/lib/module/others/other_page.dart b/lib/module/others/other_page.dart index 729360b..17153b8 100644 --- a/lib/module/others/other_page.dart +++ b/lib/module/others/other_page.dart @@ -53,7 +53,10 @@ class _OtherPageState extends ConsumerState { Text( "脚本管理", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -86,7 +89,10 @@ class _OtherPageState extends ConsumerState { Text( "依赖管理", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -121,7 +127,10 @@ class _OtherPageState extends ConsumerState { Text( "任务日志", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -161,7 +170,10 @@ class _OtherPageState extends ConsumerState { Text( "登录日志", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -177,7 +189,6 @@ class _OtherPageState extends ConsumerState { const Divider( indent: 15, ), - GestureDetector( onTap: () { if (getIt().useSecretLogined) { @@ -203,7 +214,10 @@ class _OtherPageState extends ConsumerState { Text( "修改密码", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -240,7 +254,8 @@ class _OtherPageState extends ConsumerState { Text( "夜间模式", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: + ref.watch(themeProvider).themeColor.titleColor(), fontSize: 16, ), ), @@ -270,7 +285,8 @@ class _OtherPageState extends ConsumerState { Text( "查看代码是否显示行号", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: + ref.watch(themeProvider).themeColor.titleColor(), fontSize: 16, ), ), @@ -309,7 +325,10 @@ class _OtherPageState extends ConsumerState { Text( "主题设置", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -344,7 +363,10 @@ class _OtherPageState extends ConsumerState { Text( "切换账号", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -381,7 +403,10 @@ class _OtherPageState extends ConsumerState { Text( "关于", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -440,7 +465,8 @@ class _OtherPageState extends ConsumerState { ), onPressed: () { getIt().updateToken(""); - Navigator.of(context).pushReplacementNamed(Routes.routeLogin); + Navigator.of(context) + .pushReplacementNamed(Routes.routeLogin); }, ), ], diff --git a/lib/module/others/scripts/script_code_detail_page.dart b/lib/module/others/scripts/script_code_detail_page.dart new file mode 100644 index 0000000..9dd77c8 --- /dev/null +++ b/lib/module/others/scripts/script_code_detail_page.dart @@ -0,0 +1,154 @@ +import 'package:code_text_field/code_text_field.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:highlight/languages/javascript.dart'; +import 'package:highlight/languages/json.dart'; +import 'package:highlight/languages/powershell.dart'; +import 'package:highlight/languages/python.dart'; +import 'package:highlight/languages/vbscript-html.dart'; +import 'package:highlight/languages/yaml.dart'; +import 'package:qinglong_app/base/ql_app_bar.dart'; +import 'package:qinglong_app/base/sp_const.dart'; +import 'package:qinglong_app/base/theme.dart'; +import 'package:qinglong_app/utils/sp_utils.dart'; + +/// @author NewTab +class ScriptCodeDetailPage extends ConsumerStatefulWidget { + final String title; + final String content; + + const ScriptCodeDetailPage({ + Key? key, + required this.title, + required this.content, + }) : super(key: key); + + @override + ScriptCodeDetailPageState createState() => ScriptCodeDetailPageState(); +} + +class ScriptCodeDetailPageState extends ConsumerState { + CodeController? _codeController; + GlobalKey codeFieldKey = GlobalKey(); + + bool buttonshow = false; + + void scrollToTop() { + codeFieldKey.currentState?.getCodeScroll()?.animateTo(0, + duration: const Duration(milliseconds: 200), curve: Curves.linear); + } + + void floatingButtonVisibility() { + double y = codeFieldKey.currentState?.getCodeScroll()?.offset ?? 0; + if (y > MediaQuery.of(context).size.height / 2) { + if (buttonshow == true) return; + setState(() { + buttonshow = true; + }); + } else { + if (buttonshow == false) return; + setState(() { + buttonshow = false; + }); + } + } + + String suffix = "\n\n\n"; + + @override + void dispose() { + _codeController?.dispose(); + _codeController = null; + super.dispose(); + } + + getLanguageType(String title) { + if (title.endsWith(".js")) { + return javascript; + } + + if (title.endsWith(".sh")) { + return powershell; + } + + if (title.endsWith(".py")) { + return python; + } + if (title.endsWith(".json")) { + return json; + } + if (title.endsWith(".yaml")) { + return yaml; + } + return vbscriptHtml; + } + + late String content; + + @override + void initState() { + content = widget.content; + super.initState(); + } + + @override + Widget build(BuildContext context) { + _codeController ??= CodeController( + text: (content) + suffix, + language: getLanguageType(widget.title), + onChange: (value) { + content = value + suffix; + }, + theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), + stringMap: { + "export": const TextStyle( + fontWeight: FontWeight.normal, color: Color(0xff6B2375)), + }, + ); + return Scaffold( + floatingActionButton: Visibility( + visible: buttonshow, + child: FloatingActionButton( + mini: true, + onPressed: () { + scrollToTop(); + }, + elevation: 2, + backgroundColor: Colors.white, + child: const Icon(CupertinoIcons.up_arrow), + ), + ), + appBar: QlAppBar( + canBack: true, + backCall: () { + Navigator.of(context).pop(); + }, + title: widget.title, + ), + body: SafeArea( + top: false, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, + ), + child: CodeField( + key: codeFieldKey, + controller: _codeController!, + expands: true, + readOnly: true, + wrap: SpUtil.getBool(spShowLine, defValue: false) ? false : true, + hideColumn: !SpUtil.getBool(spShowLine, defValue: false), + lineNumberStyle: LineNumberStyle( + textStyle: TextStyle( + color: ref.watch(themeProvider).themeColor.descColor(), + fontSize: 12, + ), + ), + background: Colors.white, + ), + ), + ), + ); + } +} diff --git a/lib/module/others/scripts/script_detail_page.dart b/lib/module/others/scripts/script_detail_page.dart index 57e58cf..bbe2cfb 100644 --- a/lib/module/others/scripts/script_detail_page.dart +++ b/lib/module/others/scripts/script_detail_page.dart @@ -33,7 +33,8 @@ class ScriptDetailPage extends ConsumerStatefulWidget { _ScriptDetailPageState createState() => _ScriptDetailPageState(); } -class _ScriptDetailPageState extends ConsumerState with LazyLoadState { +class _ScriptDetailPageState extends ConsumerState + with LazyLoadState { String? content; CodeController? _codeController; GlobalKey codeFieldKey = GlobalKey(); @@ -42,7 +43,8 @@ class _ScriptDetailPageState extends ConsumerState with LazyLo bool buttonshow = false; void scrollToTop() { - codeFieldKey.currentState?.getCodeScroll()?.animateTo(0, duration: const Duration(milliseconds: 200), curve: Curves.linear); + codeFieldKey.currentState?.getCodeScroll()?.animateTo(0, + duration: const Duration(milliseconds: 200), curve: Curves.linear); } void floatingButtonVisibility() { @@ -164,7 +166,8 @@ class _ScriptDetailPageState extends ConsumerState with LazyLo ), onPressed: () async { Navigator.of(context).pop(); - HttpResponse result = await Api.delScript(widget.title, widget.path ?? ""); + HttpResponse result = + await Api.delScript(widget.title, widget.path ?? ""); if (result.success) { "删除成功".toast(); Navigator.of(context).pop(true); @@ -209,7 +212,8 @@ class _ScriptDetailPageState extends ConsumerState with LazyLo }, theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), stringMap: { - "export": const TextStyle(fontWeight: FontWeight.normal, color: Color(0xff6B2375)), + "export": const TextStyle( + fontWeight: FontWeight.normal, color: Color(0xff6B2375)), }, ); } @@ -296,31 +300,34 @@ class _ScriptDetailPageState extends ConsumerState with LazyLo ), body: content == null ? const Center( - child: CupertinoActivityIndicator(), - ) + child: CupertinoActivityIndicator(), + ) : SafeArea( - top: false, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, - ), - child: CodeField( - key: codeFieldKey, - controller: _codeController!, - expands: true, - readOnly: true, - wrap: SpUtil.getBool(spShowLine, defValue: false) ? false : true, - hideColumn: !SpUtil.getBool(spShowLine, defValue: false), - lineNumberStyle: LineNumberStyle( - textStyle: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, + top: false, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: + SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, + ), + child: CodeField( + key: codeFieldKey, + controller: _codeController!, + expands: true, + readOnly: true, + wrap: SpUtil.getBool(spShowLine, defValue: false) + ? false + : true, + hideColumn: !SpUtil.getBool(spShowLine, defValue: false), + lineNumberStyle: LineNumberStyle( + textStyle: TextStyle( + color: ref.watch(themeProvider).themeColor.descColor(), + fontSize: 12, + ), + ), + background: Colors.white, + ), ), ), - background: Colors.white, - ), - ), - ), ); } @@ -337,8 +344,10 @@ class _ScriptDetailPageState extends ConsumerState with LazyLo const Duration( seconds: 1, ), - () { - codeFieldKey.currentState?.getCodeScroll()?.addListener(floatingButtonVisibility); + () { + codeFieldKey.currentState + ?.getCodeScroll() + ?.addListener(floatingButtonVisibility); }, ); } else { diff --git a/lib/module/others/scripts/script_edit_page.dart b/lib/module/others/scripts/script_edit_page.dart index 5986356..a5b918f 100644 --- a/lib/module/others/scripts/script_edit_page.dart +++ b/lib/module/others/scripts/script_edit_page.dart @@ -21,7 +21,8 @@ class ScriptEditPage extends ConsumerStatefulWidget { final String title; final String path; - const ScriptEditPage(this.title, this.path, this.content, {Key? key}) : super(key: key); + const ScriptEditPage(this.title, this.path, this.content, {Key? key}) + : super(key: key); @override _ScriptEditPageState createState() => _ScriptEditPageState(); @@ -81,7 +82,8 @@ class _ScriptEditPageState extends ConsumerState { }, theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), stringMap: { - "export": const TextStyle(fontWeight: FontWeight.normal, color: Color(0xff6B2375)), + "export": const TextStyle( + fontWeight: FontWeight.normal, color: Color(0xff6B2375)), }, ); return Scaffold( @@ -132,7 +134,8 @@ class _ScriptEditPageState extends ConsumerState { actions: [ InkWell( onTap: () async { - HttpResponse response = await Api.updateScript(widget.title, widget.path, result); + HttpResponse response = + await Api.updateScript(widget.title, widget.path, result); if (response.success) { "提交成功".toast(); Navigator.of(context).pop(true); diff --git a/lib/module/others/scripts/script_page.dart b/lib/module/others/scripts/script_page.dart index 28291c9..f435901 100644 --- a/lib/module/others/scripts/script_page.dart +++ b/lib/module/others/scripts/script_page.dart @@ -11,6 +11,8 @@ import 'package:qinglong_app/base/ui/search_cell.dart'; import 'package:qinglong_app/module/others/scripts/script_bean.dart'; import 'package:qinglong_app/utils/extension.dart'; +import 'script_upload_page.dart'; + /// @author NewTab class ScriptPage extends ConsumerStatefulWidget { const ScriptPage({Key? key}) : super(key: key); @@ -19,7 +21,8 @@ class ScriptPage extends ConsumerStatefulWidget { _ScriptPageState createState() => _ScriptPageState(); } -class _ScriptPageState extends ConsumerState with LazyLoadState { +class _ScriptPageState extends ConsumerState + with LazyLoadState { List list = []; final TextEditingController _searchController = TextEditingController(); @@ -75,7 +78,8 @@ class _ScriptPageState extends ConsumerState with LazyLoadState with LazyLoadState ListTile( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeScriptDetail, - arguments: { - "title": e.title, - "path": e.parent, + color: + ref.watch(themeProvider).themeColor.settingBgColor(), + child: + (item.children != null && item.children!.isNotEmpty) + ? ExpansionTile( + title: Text( + item.title ?? "", + style: TextStyle( + color: (item.disabled ?? false) + ? ref + .watch(themeProvider) + .themeColor + .descColor() + : ref + .watch(themeProvider) + .themeColor + .titleColor(), + fontSize: 16, + ), + ), + children: item.children! + .where((element) { + if (_searchController.text.isEmpty) { + return true; + } + return (element.title?.contains( + _searchController.text) ?? + false) || + (element.value?.contains( + _searchController.text) ?? + false); + }) + .map((e) => ListTile( + onTap: () { + Navigator.of(context).pushNamed( + Routes.routeScriptDetail, + arguments: { + "title": e.title, + "path": e.parent, + }, + ).then((value) { + if (value != null && + value == true) { + loadData(); + } + }); }, - ).then((value) { - if (value != null && value == true) { - loadData(); - } - }); - }, - title: Text( - e.title ?? "", - style: TextStyle( - color: (item.disabled ?? false) - ? ref.watch(themeProvider).themeColor.descColor() - : ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 14, - ), - ), - )) - .toList(), - ) - : ListTile( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeScriptDetail, - arguments: { - "title": item.title, - "path": "", + title: Text( + e.title ?? "", + style: TextStyle( + color: (item.disabled ?? false) + ? ref + .watch(themeProvider) + .themeColor + .descColor() + : ref + .watch(themeProvider) + .themeColor + .titleColor(), + fontSize: 14, + ), + ), + )) + .toList(), + ) + : ListTile( + onTap: () { + Navigator.of(context).pushNamed( + Routes.routeScriptDetail, + arguments: { + "title": item.title, + "path": "", + }, + ).then( + (value) { + if (value != null && value == true) { + loadData(); + } + }, + ); }, - ).then( - (value) { - if (value != null && value == true) { - loadData(); - } - }, - ); - }, - title: Text( - item.title ?? "", - style: TextStyle( - color: (item.disabled ?? false) - ? ref.watch(themeProvider).themeColor.descColor() - : ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 16, + title: Text( + item.title ?? "", + style: TextStyle( + color: (item.disabled ?? false) + ? ref + .watch(themeProvider) + .themeColor + .descColor() + : ref + .watch(themeProvider) + .themeColor + .titleColor(), + fontSize: 16, + ), + ), ), - ), - ), ); } else { return const SizedBox.shrink(); @@ -209,144 +241,12 @@ class _ScriptPageState extends ConsumerState with LazyLoadState CupertinoAlertDialog( - title: const Text("新增脚本"), - content: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox( - height: 10, - ), - const Text( - "脚本名称:", - style: TextStyle( - fontSize: 14, - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: Material( - color: Colors.transparent, - child: TextField( - controller: _nameController, - decoration: const InputDecoration( - isDense: true, - contentPadding: EdgeInsets.all(4), - hintText: "请输入脚本名称", - hintStyle: TextStyle( - fontSize: 14, - ), - ), - autofocus: false, - ), - ), - ), - const SizedBox( - height: 10, - ), - const Material( - color: Colors.transparent, - child: Text( - "脚本所属文件夹:", - style: TextStyle( - fontSize: 14, - ), - ), - ), - const SizedBox( - height: 10, - ), - Material( - color: Colors.transparent, - child: DropdownButtonFormField( - items: list - .where((element) => element.children?.isNotEmpty ?? false) - .map((e) => DropdownMenuItem( - value: e.value, - child: SizedBox( - width: MediaQuery.of(context).size.width / 2, - child: Text( - e.value ?? "", - maxLines: 2, - ), - ), - )) - .toList() - ..insert( - 0, - DropdownMenuItem( - value: "", - child: SizedBox( - width: MediaQuery.of(context).size.width / 2, - child: const Text( - "根目录", - maxLines: 2, - ), - ), - )), - value: scriptPath, - onChanged: (value) { - scriptPath = value ?? ""; - }, - ), - ), - ], - ), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () async { - "提交中...".toast(); - HttpResponse response = await Api.addScript( - _nameController.text, - scriptPath, - "## created by 青龙客户端 ${DateTime.now()}\n\n", - ); - if (response.success) { - "提交成功".toast(); - Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - Routes.routeScriptUpdate, - arguments: { - "title": _nameController.text, - "path": scriptPath, - "content": "## created by 青龙客户端 ${DateTime.now()}\n\n", - }, - ).then((value) { - if (value != null && value == true) { - _nameController.text = ""; - loadData(); - } - }); - } else { - (response.message ?? "").toast(); - } - }, - ), - ], - ), - ); + List paths = list + .where((element) => element.children?.isNotEmpty ?? false) + .map((e) => e.title) + .toList(); + + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => ScriptUploadPage(paths: paths))); } } diff --git a/lib/module/others/scripts/script_upload_page.dart b/lib/module/others/scripts/script_upload_page.dart new file mode 100644 index 0000000..10c1896 --- /dev/null +++ b/lib/module/others/scripts/script_upload_page.dart @@ -0,0 +1,425 @@ +import 'dart:io'; +import 'dart:math'; + +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:qinglong_app/base/http/api.dart'; +import 'package:qinglong_app/base/http/http.dart'; +import 'package:qinglong_app/base/ql_app_bar.dart'; +import 'package:qinglong_app/base/routes.dart'; +import 'package:qinglong_app/base/theme.dart'; +import 'package:path/path.dart'; +import 'package:qinglong_app/module/others/scripts/script_code_detail_page.dart'; +import 'package:qinglong_app/module/task/task_bean.dart'; +import 'package:qinglong_app/utils/extension.dart'; + +/// @author NewTab + +class ScriptUploadPage extends ConsumerStatefulWidget { + final List paths; + + const ScriptUploadPage({ + Key? key, + required this.paths, + }) : super(key: key); + + @override + ConsumerState createState() => ScriptUploadPageState(); +} + +class ScriptUploadPageState extends ConsumerState { + List list = []; + + final TextEditingController _nameController = TextEditingController(); + String scriptPath = ""; + File? file; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: QlAppBar( + title: "新增脚本", + actions: [ + InkWell( + onTap: () { + submit(context); + }, + child: const Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, + ), + child: Center( + child: Text( + "提交", + style: TextStyle( + color: Colors.white, + fontSize: 16, + ), + ), + ), + ), + ) + ], + ), + body: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 15, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 30, + ), + const TitleWidget( + "脚本名称", + ), + TextField( + controller: _nameController, + decoration: InputDecoration( + contentPadding: const EdgeInsets.fromLTRB(0, 5, 0, 5), + hintText: "请输入脚本名称", + hintStyle: TextStyle( + fontSize: 14, + color: ref.watch(themeProvider).themeColor.descColor(), + ), + ), + autofocus: false, + ), + const SizedBox( + height: 30, + ), + const TitleWidget( + "脚本目录", + ), + const SizedBox( + height: 10, + ), + DropdownButtonFormField( + items: widget.paths + .map((e) => DropdownMenuItem( + value: e, + child: SizedBox( + width: MediaQuery.of(context).size.width / 2, + child: Text( + e ?? "", + maxLines: 2, + ), + ), + )) + .toList() + ..insert( + 0, + DropdownMenuItem( + value: "", + child: SizedBox( + width: MediaQuery.of(context).size.width / 2, + child: const Text( + "根目录", + maxLines: 2, + ), + ), + ), + ), + style: TextStyle( + fontSize: 14, + color: ref.watch(themeProvider).themeColor.titleColor(), + ), + decoration: const InputDecoration( + isDense: true, + contentPadding: EdgeInsets.symmetric( + vertical: 15, + ), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide( + color: Color(0xfff5f5f5), + ), + ), + border: UnderlineInputBorder( + borderSide: BorderSide( + color: Color(0xfff5f5f5), + ), + ), + ), + value: scriptPath, + onChanged: (value) { + scriptPath = value ?? ""; + }, + ), + const SizedBox( + height: 30, + ), + const TitleWidget( + "上传脚本", + ), + const SizedBox( + height: 10, + ), + Container( + height: 80, + alignment: Alignment.centerLeft, + child: file == null ? addWidget() : addedWidget(context), + ), + ], + ), + ), + const SizedBox( + height: 50, + ), + ], + ), + ), + ); + } + + Widget addWidget() { + return GestureDetector( + onTap: () async { + FilePickerResult? result = await FilePicker.platform.pickFiles(); + if (result != null && + result.files.isNotEmpty && + result.files.single.path != null) { + file = File(result.files.single.path!); + + if (file == null) return; + if (file!.lengthSync() > 5242880) { + file = null; + "最大支持上传5M的文件".toast(); + return; + } + + _nameController.text = getFileName(); + setState(() {}); + } + }, + child: Container( + margin: const EdgeInsets.only( + top: 10, + ), + width: 70, + height: 70, + decoration: BoxDecoration( + color: const Color(0xfff3f5f7), + borderRadius: BorderRadius.circular(5), + ), + child: Center( + child: Image.asset( + "assets/images/icon_add_file.png", + width: 50, + fit: BoxFit.cover, + ), + ), + ), + ); + } + + Widget addedWidget(BuildContext context) { + return GestureDetector( + onTap: () async { + try { + String content = await file!.readAsString(); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ScriptCodeDetailPage( + title: getFileName(), + content: content, + ), + ), + ); + } catch (e) { + e.toString().toast(); + } + }, + behavior: HitTestBehavior.opaque, + child: Container( + height: 80, + padding: const EdgeInsets.symmetric( + vertical: 10, + ), + child: Row( + children: [ + Image.asset( + getIconBySuffix(), + width: 50, + fit: BoxFit.cover, + ), + const SizedBox( + width: 15, + ), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + getFileName(), + style: TextStyle( + color: ref.watch(themeProvider).themeColor.titleColor(), + fontSize: 16, + ), + ), + const SizedBox( + height: 5, + ), + Text( + getFileSize(file!.path, 1), + style: TextStyle( + color: ref.watch(themeProvider).themeColor.descColor(), + fontSize: 12, + ), + ), + ], + ), + ), + const Spacer(), + GestureDetector( + onTap: () { + file = null; + _nameController.text = ""; + setState(() {}); + }, + child: Icon( + CupertinoIcons.clear, + size: 20, + color: ref.watch(themeProvider).themeColor.descColor(), + ), + ), + ], + ), + ), + ); + } + + String getFileSize(String filepath, int decimals) { + var file = File(filepath); + int bytes = file.lengthSync(); + if (bytes <= 0) return "0 B"; + const suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + var i = (log(bytes) / log(1024)).floor(); + return '${(bytes / pow(1024, i)).toStringAsFixed(decimals)} ${suffixes[i]}'; + } + + String getFileName() { + return basename(file!.path); + } + + String getIconBySuffix() { + String end = file!.path; + + if (end.endsWith(".py")) { + return "assets/images/py.png"; + } + if (end.endsWith(".js")) { + return "assets/images/js.png"; + } + if (end.endsWith(".ts")) { + return "assets/images/ts.png"; + } + if (end.endsWith(".json")) { + return "assets/images/json.png"; + } + if (end.endsWith(".sh")) { + return "assets/images/shell.png"; + } + return "assets/images/other.png"; + } + + void submit(BuildContext context) async { + try { + if (_nameController.text.isEmpty) { + "请输入文件名称".toast(); + return; + } + + if (file == null) { + Navigator.of(context).pushNamed( + Routes.routeScriptAdd, + arguments: { + "title": _nameController.text, + "path": scriptPath, + }, + ).then((value) { + if (value != null && value == true) { + Navigator.of(context).pop(true); + } + }); + } else { + String content = await file!.readAsString(); + HttpResponse response = await Api.addScript( + _nameController.text, + scriptPath, + content, + ); + if (response.success) { + "提交成功".toast(); + + String command = + "task $scriptPath${(scriptPath.isNotEmpty) ? separator : ""}${getFileName()} "; + + String? cron = getCronString(content, getFileName()); + Navigator.of(context).popAndPushNamed( + Routes.routeAddTask, + arguments: TaskBean( + name: _nameController.text, + command: command, + schedule: cron, + ), + ); + } else { + (response.message ?? "").toast(); + } + } + } catch (e) { + e.toString().toast(); + } + } + + static String? getCronString(String pre, String fileName) { + String reg = + "([\\d\\*]*[\\*-\\/,\\d]*[\\d\\*] ){4,5}[\\d\\*]*[\\*-\\/,\\d]*[\\d\\*]( |,|\").*$fileName"; + RegExp regExp = RegExp(reg); + RegExpMatch? result = regExp.firstMatch(pre); + return result?[0]?.replaceAll(fileName, "").trim(); + } +} + +class TitleWidget extends ConsumerWidget { + final String title; + final bool required; + + const TitleWidget( + this.title, { + Key? key, + this.required = false, + }) : super(key: key); + + @override + Widget build(BuildContext context, ref) { + return RichText( + text: TextSpan( + text: !required ? "" : "* ", + style: const TextStyle( + color: Color(0xFFF02D2D), + ), + children: [ + TextSpan( + text: title, + style: TextStyle( + fontSize: 16, + color: ref.watch(themeProvider).themeColor.titleColor(), + ), + ), + ], + ), + ); + } +} diff --git a/lib/module/others/task_log/task_log_detail_page.dart b/lib/module/others/task_log/task_log_detail_page.dart index dfcd3b6..93948e9 100644 --- a/lib/module/others/task_log/task_log_detail_page.dart +++ b/lib/module/others/task_log/task_log_detail_page.dart @@ -24,7 +24,8 @@ class TaskLogDetailPage extends ConsumerStatefulWidget { _TaskLogDetailPageState createState() => _TaskLogDetailPageState(); } -class _TaskLogDetailPageState extends ConsumerState with LazyLoadState { +class _TaskLogDetailPageState extends ConsumerState + with LazyLoadState { String? content; @override @@ -40,15 +41,15 @@ class _TaskLogDetailPageState extends ConsumerState with Lazy body: content == null ? const Center(child: CupertinoActivityIndicator()) : Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: SelectableText( - (content == null || content!.isEmpty) ? "暂无数据" : content!, - selectionHeightStyle: BoxHeightStyle.max, - selectionWidthStyle: BoxWidthStyle.max, - ), - ), + padding: const EdgeInsets.symmetric( + horizontal: 15, + ), + child: SelectableText( + (content == null || content!.isEmpty) ? "暂无数据" : content!, + selectionHeightStyle: BoxHeightStyle.max, + selectionWidthStyle: BoxWidthStyle.max, + ), + ), ); } diff --git a/lib/module/others/task_log/task_log_page.dart b/lib/module/others/task_log/task_log_page.dart index 2541940..d873c85 100644 --- a/lib/module/others/task_log/task_log_page.dart +++ b/lib/module/others/task_log/task_log_page.dart @@ -19,7 +19,8 @@ class TaskLogPage extends ConsumerStatefulWidget { _TaskLogPageState createState() => _TaskLogPageState(); } -class _TaskLogPageState extends ConsumerState with LazyLoadState { +class _TaskLogPageState extends ConsumerState + with LazyLoadState { List list = []; final TextEditingController _searchController = TextEditingController(); @@ -63,7 +64,8 @@ class _TaskLogPageState extends ConsumerState with LazyLoadState with LazyLoadState with LazyLoadState ListTile( onTap: () { - Navigator.of(context).pushNamed(Routes.routeTaskLogDetail, arguments: { - "path": item.name, - "title": e, - }); + Navigator.of(context).pushNamed( + Routes.routeTaskLogDetail, + arguments: { + "path": item.name, + "title": e, + }); }, title: Text( e, style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 14, ), ), @@ -98,15 +108,20 @@ class _TaskLogPageState extends ConsumerState with LazyLoadState ListTile( onTap: () { - Navigator.of(context).pushNamed(Routes.routeTaskLogDetail, arguments: { - "path": item.name, - "title": e.title, - }); + Navigator.of(context).pushNamed( + Routes.routeTaskLogDetail, + arguments: { + "path": item.name, + "title": e.title, + }); }, title: Text( e.title ?? "", style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 14, ), ), @@ -119,15 +134,20 @@ class _TaskLogPageState extends ConsumerState with LazyLoadState { ), child: Column( mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -144,7 +145,8 @@ class _ThemePageState extends ConsumerState { child: CircularProgressIndicator( strokeWidth: 2, - color: _primaryColor, + color: + _primaryColor, ), ), SizedBox( @@ -158,8 +160,8 @@ class _ThemePageState extends ConsumerState { child: Text( "示例名称", maxLines: 1, - overflow: - TextOverflow.ellipsis, + overflow: TextOverflow + .ellipsis, style: TextStyle( overflow: TextOverflow .ellipsis, @@ -182,7 +184,8 @@ class _ThemePageState extends ConsumerState { "上午10:00", maxLines: 1, style: TextStyle( - overflow: TextOverflow.ellipsis, + overflow: + TextOverflow.ellipsis, color: ref .watch(themeProvider) .themeColor @@ -216,7 +219,8 @@ class _ThemePageState extends ConsumerState { "10 1-12/2 * * *", maxLines: 1, style: TextStyle( - overflow: TextOverflow.ellipsis, + overflow: + TextOverflow.ellipsis, color: ref .watch(themeProvider) .themeColor diff --git a/lib/module/task/add_task_page.dart b/lib/module/task/add_task_page.dart index 401b64b..4aed39b 100644 --- a/lib/module/task/add_task_page.dart +++ b/lib/module/task/add_task_page.dart @@ -207,8 +207,11 @@ class _AddTaskPageState extends ConsumerState { taskBean.command = _commandController.text; taskBean.schedule = _cronController.text; HttpResponse response = await Api.addTask( - _nameController.text, _commandController.text, _cronController.text, - id: taskBean.id,); + _nameController.text, + _commandController.text, + _cronController.text, + id: taskBean.id, + ); if (response.success) { (widget.taskBean?.sId == null) ? "新增成功" : "修改成功".toast(); diff --git a/lib/module/task/intime_log/intime_log_page.dart b/lib/module/task/intime_log/intime_log_page.dart index 0eee050..c9ca864 100644 --- a/lib/module/task/intime_log/intime_log_page.dart +++ b/lib/module/task/intime_log/intime_log_page.dart @@ -39,8 +39,7 @@ class _InTimeLogPageState extends State if (!canRequest) return; if (isRequest) return; isRequest = true; - HttpResponse response = - await Api.inTimeLog(widget.cronId); + HttpResponse response = await Api.inTimeLog(widget.cronId); if (response.success) { content = response.bean; setState(() {}); @@ -161,7 +160,7 @@ class _InTimeLogPageState extends State if (widget.needTimer) { _timer = Timer.periodic( const Duration(seconds: 2), - (timer) { + (timer) { getLogData(); }, ); diff --git a/lib/module/task/task_bean.dart b/lib/module/task/task_bean.dart index 97a9c3a..02faf57 100644 --- a/lib/module/task/task_bean.dart +++ b/lib/module/task/task_bean.dart @@ -26,20 +26,20 @@ class TaskBean { TaskBean( {this.name, - this.command, - this.schedule, - this.saved, - this.sId, - this.created, - this.status, - this.timestamp, - this.isSystem, - this.isDisabled, - this.logPath, - this.isPinned, - this.lastExecutionTime, - this.lastRunningTime, - this.pid}); + this.command, + this.schedule, + this.saved, + this.sId, + this.created, + this.status, + this.timestamp, + this.isSystem, + this.isDisabled, + this.logPath, + this.isPinned, + this.lastExecutionTime, + this.lastRunningTime, + this.pid}); get nId => _id; @@ -51,7 +51,9 @@ class TaskBean { saved = json['saved']; id = json['id']; _id = json['_id']; - sId = json.containsKey('_id') ? json['_id'].toString() : (json.containsKey('id') ? json['id'].toString() : ""); + sId = json.containsKey('_id') + ? json['_id'].toString() + : (json.containsKey('id') ? json['id'].toString() : ""); created = int.tryParse(json['created'].toString()); status = json['status']; timestamp = json['timestamp'].toString(); diff --git a/lib/module/task/task_detail/task_detail_page.dart b/lib/module/task/task_detail/task_detail_page.dart index ae19b57..083c7e6 100644 --- a/lib/module/task/task_detail/task_detail_page.dart +++ b/lib/module/task/task_detail/task_detail_page.dart @@ -17,7 +17,8 @@ class TaskDetailPage extends ConsumerStatefulWidget { final TaskBean taskBean; final bool hideAppbar; - const TaskDetailPage(this.taskBean, {Key? key, this.hideAppbar = false}) : super(key: key); + const TaskDetailPage(this.taskBean, {Key? key, this.hideAppbar = false}) + : super(key: key); @override _TaskDetailPageState createState() => _TaskDetailPageState(); @@ -71,11 +72,13 @@ class _TaskDetailPageState extends ConsumerState { ), TaskDetailCell( title: "创建时间", - desc: Utils.formatMessageTime(widget.taskBean.created ?? 0), + desc: + Utils.formatMessageTime(widget.taskBean.created ?? 0), ), TaskDetailCell( title: "更新时间", - desc: Utils.formatGMTTime(widget.taskBean.timestamp ?? ""), + desc: + Utils.formatGMTTime(widget.taskBean.timestamp ?? ""), ), TaskDetailCell( title: "任务定时", @@ -83,11 +86,14 @@ class _TaskDetailPageState extends ConsumerState { ), TaskDetailCell( title: "最后运行时间", - desc: Utils.formatMessageTime(widget.taskBean.lastExecutionTime ?? 0), + desc: Utils.formatMessageTime( + widget.taskBean.lastExecutionTime ?? 0), ), TaskDetailCell( title: "最后运行时长", - desc: widget.taskBean.lastRunningTime == null ? "-" : "${widget.taskBean.lastRunningTime ?? "-"}秒", + desc: widget.taskBean.lastRunningTime == null + ? "-" + : "${widget.taskBean.lastRunningTime ?? "-"}秒", ), GestureDetector( behavior: HitTestBehavior.opaque, @@ -205,7 +211,8 @@ class _TaskDetailPageState extends ConsumerState { behavior: HitTestBehavior.opaque, onTap: () { Navigator.of(context).pop(); - Navigator.of(context).pushNamed(Routes.routeAddTask, arguments: widget.taskBean); + Navigator.of(context) + .pushNamed(Routes.routeAddTask, arguments: widget.taskBean); }, child: Container( padding: const EdgeInsets.symmetric( @@ -357,12 +364,16 @@ class _TaskDetailPageState extends ConsumerState { } void enableTask() async { - await ref.read(taskProvider).enableTask(widget.taskBean.sId!, widget.taskBean.isDisabled!); + await ref + .read(taskProvider) + .enableTask(widget.taskBean.sId!, widget.taskBean.isDisabled!); setState(() {}); } void pinTask() async { - await ref.read(taskProvider).pinTask(widget.taskBean.sId!, widget.taskBean.isPinned!); + await ref + .read(taskProvider) + .pinTask(widget.taskBean.sId!, widget.taskBean.isPinned!); setState(() {}); } @@ -472,14 +483,16 @@ class TaskDetailCell extends ConsumerWidget { } }, style: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), + color: + ref.watch(themeProvider).themeColor.descColor(), fontSize: 14, ), ), ), ) : Expanded( - child: Align(alignment: Alignment.centerRight, child: icon!), + child: + Align(alignment: Alignment.centerRight, child: icon!), ), ], ), diff --git a/lib/module/task/task_page.dart b/lib/module/task/task_page.dart index 6a5bce7..390ed3d 100644 --- a/lib/module/task/task_page.dart +++ b/lib/module/task/task_page.dart @@ -67,9 +67,17 @@ class _TaskPageState extends ConsumerState { } TaskBean item = list[index - 1]; if (_searchController.text.isEmpty || - (item.name?.toLowerCase().contains(_searchController.text.toLowerCase()) ?? false) || - (item.command?.toLowerCase().contains(_searchController.text.toLowerCase()) ?? false) || - (item.schedule?.contains(_searchController.text.toLowerCase()) ?? false)) { + (item.name + ?.toLowerCase() + .contains(_searchController.text.toLowerCase()) ?? + false) || + (item.command + ?.toLowerCase() + .contains(_searchController.text.toLowerCase()) ?? + false) || + (item.schedule + ?.contains(_searchController.text.toLowerCase()) ?? + false)) { return TaskItemCell(item, ref); } else { return const SizedBox.shrink(); @@ -80,9 +88,17 @@ class _TaskPageState extends ConsumerState { if (index == 0) return const SizedBox.shrink(); TaskBean item = list[index - 1]; if (_searchController.text.isEmpty || - (item.name?.toLowerCase().contains(_searchController.text.toLowerCase()) ?? false) || - (item.command?.toLowerCase().contains(_searchController.text.toLowerCase()) ?? false) || - (item.schedule?.contains(_searchController.text.toLowerCase()) ?? false)) { + (item.name + ?.toLowerCase() + .contains(_searchController.text.toLowerCase()) ?? + false) || + (item.command + ?.toLowerCase() + .contains(_searchController.text.toLowerCase()) ?? + false) || + (item.schedule + ?.contains(_searchController.text.toLowerCase()) ?? + false)) { return Container( color: ref.watch(themeProvider).themeColor.settingBgColor(), child: const Divider( @@ -130,7 +146,9 @@ class _TaskPageState extends ConsumerState { child: Text( TaskViewModel.allStr, style: TextStyle( - color: currentState == TaskViewModel.allStr ? ref.watch(themeProvider).primaryColor : ref.watch(themeProvider).themeColor.titleColor(), + color: currentState == TaskViewModel.allStr + ? ref.watch(themeProvider).primaryColor + : ref.watch(themeProvider).themeColor.titleColor(), fontSize: 14, ), ), @@ -140,8 +158,9 @@ class _TaskPageState extends ConsumerState { child: Text( TaskViewModel.runningStr, style: TextStyle( - color: - currentState == TaskViewModel.runningStr ? ref.watch(themeProvider).primaryColor : ref.watch(themeProvider).themeColor.titleColor(), + color: currentState == TaskViewModel.runningStr + ? ref.watch(themeProvider).primaryColor + : ref.watch(themeProvider).themeColor.titleColor(), fontSize: 14, ), ), @@ -151,7 +170,9 @@ class _TaskPageState extends ConsumerState { child: Text( TaskViewModel.neverStr, style: TextStyle( - color: currentState == TaskViewModel.neverStr ? ref.watch(themeProvider).primaryColor : ref.watch(themeProvider).themeColor.titleColor(), + color: currentState == TaskViewModel.neverStr + ? ref.watch(themeProvider).primaryColor + : ref.watch(themeProvider).themeColor.titleColor(), fontSize: 14, ), ), @@ -165,7 +186,10 @@ class _TaskPageState extends ConsumerState { style: TextStyle( color: currentState == TaskViewModel.notScriptStr ? ref.watch(themeProvider).primaryColor - : ref.watch(themeProvider).themeColor.titleColor(), + : ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 14, ), ), @@ -178,8 +202,9 @@ class _TaskPageState extends ConsumerState { TaskViewModel.disableStr, style: TextStyle( fontSize: 14, - color: - currentState == TaskViewModel.disableStr ? ref.watch(themeProvider).primaryColor : ref.watch(themeProvider).themeColor.titleColor(), + color: currentState == TaskViewModel.disableStr + ? ref.watch(themeProvider).primaryColor + : ref.watch(themeProvider).themeColor.titleColor(), ), ), value: TaskViewModel.disableStr, @@ -236,7 +261,9 @@ class TaskItemCell extends StatelessWidget { @override Widget build(BuildContext context) { return ColoredBox( - color: bean.isPinned == 1 ? ref.watch(themeProvider).themeColor.pinColor() : ref.watch(themeProvider).themeColor.settingBgColor(), + color: bean.isPinned == 1 + ? ref.watch(themeProvider).themeColor.pinColor() + : ref.watch(themeProvider).themeColor.settingBgColor(), child: Slidable( key: ValueKey(bean.sId), endActionPane: ActionPane( @@ -247,7 +274,8 @@ class TaskItemCell extends StatelessWidget { backgroundColor: const Color(0xff5D5E70), onPressed: (_) { WidgetsBinding.instance.endOfFrame.then((timeStamp) { - Navigator.of(context).pushNamed(Routes.routeAddTask, arguments: bean); + Navigator.of(context) + .pushNamed(Routes.routeAddTask, arguments: bean); }); }, foregroundColor: Colors.white, @@ -259,7 +287,9 @@ class TaskItemCell extends StatelessWidget { pinTask(context); }, foregroundColor: Colors.white, - icon: (bean.isPinned ?? 0) == 0 ? CupertinoIcons.pin : CupertinoIcons.pin_slash, + icon: (bean.isPinned ?? 0) == 0 + ? CupertinoIcons.pin + : CupertinoIcons.pin_slash, ), SlidableAction( backgroundColor: const Color(0xffA356D6), @@ -267,7 +297,9 @@ class TaskItemCell extends StatelessWidget { enableTask(context); }, foregroundColor: Colors.white, - icon: bean.isDisabled! == 0 ? Icons.dnd_forwardslash : Icons.check_circle_outline_sharp, + icon: bean.isDisabled! == 0 + ? Icons.dnd_forwardslash + : Icons.check_circle_outline_sharp, ), SlidableAction( backgroundColor: const Color(0xffEA4D3E), @@ -299,7 +331,9 @@ class TaskItemCell extends StatelessWidget { } }, foregroundColor: Colors.white, - icon: bean.status! == 1 ? CupertinoIcons.memories : CupertinoIcons.stop_circle, + icon: bean.status! == 1 + ? CupertinoIcons.memories + : CupertinoIcons.stop_circle, ), SlidableAction( backgroundColor: const Color(0xff606467), @@ -317,10 +351,13 @@ class TaskItemCell extends StatelessWidget { ], ), child: Material( - color: bean.isPinned == 1 ? ref.watch(themeProvider).themeColor.pinColor() : ref.watch(themeProvider).themeColor.settingBgColor(), + color: bean.isPinned == 1 + ? ref.watch(themeProvider).themeColor.pinColor() + : ref.watch(themeProvider).themeColor.settingBgColor(), child: InkWell( onTap: () { - Navigator.of(context).pushNamed(Routes.routeTaskDetail, arguments: bean); + Navigator.of(context) + .pushNamed(Routes.routeTaskDetail, arguments: bean); }, child: Container( width: MediaQuery.of(context).size.width, @@ -356,7 +393,10 @@ class TaskItemCell extends StatelessWidget { overflow: TextOverflow.ellipsis, style: TextStyle( overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.titleColor(), + color: ref + .watch(themeProvider) + .themeColor + .titleColor(), fontSize: 16, ), ), @@ -392,11 +432,16 @@ class TaskItemCell extends StatelessWidget { Material( color: Colors.transparent, child: Text( - (bean.lastExecutionTime == null || bean.lastExecutionTime == 0) ? "-" : Utils.formatMessageTime(bean.lastExecutionTime!), + (bean.lastExecutionTime == null || + bean.lastExecutionTime == 0) + ? "-" + : Utils.formatMessageTime( + bean.lastExecutionTime!), maxLines: 1, style: TextStyle( overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), + color: + ref.watch(themeProvider).themeColor.descColor(), fontSize: 12, ), ), diff --git a/lib/module/task/task_viewmodel.dart b/lib/module/task/task_viewmodel.dart index a2f7fd3..48ec5ed 100644 --- a/lib/module/task/task_viewmodel.dart +++ b/lib/module/task/task_viewmodel.dart @@ -62,7 +62,8 @@ class TaskViewModel extends BaseViewModel { } p.sort((TaskBean a, TaskBean b) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0).isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); + bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) + .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); if (c == true) { return 1; } @@ -75,7 +76,8 @@ class TaskViewModel extends BaseViewModel { p.sort((a, b) { if (a.status == 0 && b.status == 0) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0).isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); + bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) + .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); if (c == true) { return 1; } @@ -86,7 +88,8 @@ class TaskViewModel extends BaseViewModel { }); r.sort((a, b) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0).isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); + bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) + .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); if (c == true) { return 1; } @@ -94,7 +97,8 @@ class TaskViewModel extends BaseViewModel { }); d.sort((a, b) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0).isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); + bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) + .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); if (c == true) { return 1; } @@ -102,7 +106,8 @@ class TaskViewModel extends BaseViewModel { }); list.sort((a, b) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0).isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); + bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) + .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); if (c == true) { return 1; } @@ -116,9 +121,12 @@ class TaskViewModel extends BaseViewModel { running.clear(); running.addAll(list.where((element) => element.status == 0)); neverRunning.clear(); - neverRunning.addAll(list.where((element) => element.lastRunningTime == null)); + neverRunning + .addAll(list.where((element) => element.lastRunningTime == null)); notScripts.clear(); - notScripts.addAll(list.where((element) => (element.command != null && (element.command!.startsWith("ql repo") || element.command!.startsWith("ql raw"))))); + notScripts.addAll(list.where((element) => (element.command != null && + (element.command!.startsWith("ql repo") || + element.command!.startsWith("ql raw"))))); disabled.clear(); disabled.addAll(list.where((element) => element.isDisabled == 1)); } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 487886d..4d11b56 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -9,6 +9,7 @@ class Utils { static bool isUpperVersion() { return systemBean.isUpperVersion(); } + static bool isUpperVersion2_12_2() { return systemBean.isUpperVersion2_12_2(); } diff --git a/pub/code_field-master/example/lib/readme/fib.dart b/pub/code_field-master/example/lib/readme/fib.dart index cee4bba..2bf2908 100644 --- a/pub/code_field-master/example/lib/readme/fib.dart +++ b/pub/code_field-master/example/lib/readme/fib.dart @@ -2,12 +2,10 @@ // recursive implementation int fibonacci(int n) { if (n <= 1) return n; - return fibonacci(n - 1) - + fibonacci(n - 2); + return fibonacci(n - 1) + fibonacci(n - 2); } void main() { print("Fibonacci sequence:"); - for (var n = 0; n < 10; n++) - print(fibonacci(n)); + for (var n = 0; n < 10; n++) print(fibonacci(n)); } diff --git a/pub/code_field-master/lib/src/code_controller.dart b/pub/code_field-master/lib/src/code_controller.dart index 9cb5f02..e355ea0 100644 --- a/pub/code_field-master/lib/src/code_controller.dart +++ b/pub/code_field-master/lib/src/code_controller.dart @@ -64,7 +64,8 @@ class CodeController extends TextEditingController { this.onChange, }) : super(text: text) { // PatternMap - if (language != null && theme == null) throw Exception("A theme must be provided for language parsing"); + if (language != null && theme == null) + throw Exception("A theme must be provided for language parsing"); // Register language if (language != null) { highlight.registerLanguage(languageId, language!); @@ -152,7 +153,8 @@ class CodeController extends TextEditingController { const _chars = 'abcdefghijklmnopqrstuvwxyz1234567890'; final _rnd = Random(); return String.fromCharCodes( - Iterable.generate(10, (_) => _chars.codeUnitAt(_rnd.nextInt(_chars.length))), + Iterable.generate( + 10, (_) => _chars.codeUnitAt(_rnd.nextInt(_chars.length))), ); } @@ -178,8 +180,11 @@ class CodeController extends TextEditingController { } } // Now fix the textfield for web - if (_webSpaceFix) newValue = newValue.copyWith(text: _spacesToMiddleDots(newValue.text)); - if (onChange != null) onChange!(_webSpaceFix ? _middleDotsToSpaces(newValue.text) : newValue.text); + if (_webSpaceFix) + newValue = newValue.copyWith(text: _spacesToMiddleDots(newValue.text)); + if (onChange != null) + onChange!( + _webSpaceFix ? _middleDotsToSpaces(newValue.text) : newValue.text); super.value = newValue; } @@ -190,7 +195,11 @@ class CodeController extends TextEditingController { onMatch: (Match m) { if (styleList.isEmpty) return ''; int idx; - for (idx = 1; idx < m.groupCount && idx <= styleList.length && m.group(idx) == null; idx++) {} + for (idx = 1; + idx < m.groupCount && + idx <= styleList.length && + m.group(idx) == null; + idx++) {} children.add(TextSpan( text: m[0], style: styleList[idx - 1], @@ -221,7 +230,8 @@ class CodeController extends TextEditingController { if (val != null) { if (_webSpaceFix) val = _spacesToMiddleDots(val); var child = TextSpan(text: val, style: theme?[node.className]); - if (styleRegExp != null) child = _processPatterns(val, theme?[node.className]); + if (styleRegExp != null) + child = _processPatterns(val, theme?[node.className]); currentSpans.add(child); } else if (nodeChildren != null) { List tmp = []; @@ -245,7 +255,8 @@ class CodeController extends TextEditingController { } @override - TextSpan buildTextSpan({required BuildContext context, TextStyle? style, bool? withComposing}) { + TextSpan buildTextSpan( + {required BuildContext context, TextStyle? style, bool? withComposing}) { // Retrieve pattern regexp final patternList = []; if (_webSpaceFix) { diff --git a/pub/code_field-master/lib/src/code_field.dart b/pub/code_field-master/lib/src/code_field.dart index 7dc188d..fa442aa 100644 --- a/pub/code_field-master/lib/src/code_field.dart +++ b/pub/code_field-master/lib/src/code_field.dart @@ -12,14 +12,16 @@ class LineNumberController extends TextEditingController { LineNumberController(this.lineNumberBuilder); @override - TextSpan buildTextSpan({required BuildContext context, TextStyle? style, bool? withComposing}) { + TextSpan buildTextSpan( + {required BuildContext context, TextStyle? style, bool? withComposing}) { final children = []; final list = text.split("\n"); for (int k = 0; k < list.length; k++) { final el = list[k]; final number = int.parse(el); var textSpan = TextSpan(text: el, style: style); - if (lineNumberBuilder != null) textSpan = lineNumberBuilder!(number, style); + if (lineNumberBuilder != null) + textSpan = lineNumberBuilder!(number, style); children.add(textSpan); if (k < list.length - 1) children.add(TextSpan(text: "\n")); } @@ -199,7 +201,8 @@ class CodeFieldState extends State { } // Wrap the codeField in a horizontal scrollView - Widget _wrapInScrollView(Widget codeField, TextStyle textStyle, double minWidth) { + Widget _wrapInScrollView( + Widget codeField, TextStyle textStyle, double minWidth) { final leftPad = widget.lineNumberStyle.margin / 2; final intrinsic = IntrinsicWidth( child: Column( @@ -239,7 +242,8 @@ class CodeFieldState extends State { final defaultText = Colors.grey.shade200; final theme = widget.controller.theme; - Color? backgroundCol = widget.background ?? theme?[ROOT_KEY]?.backgroundColor ?? defaultBg; + Color? backgroundCol = + widget.background ?? theme?[ROOT_KEY]?.backgroundColor ?? defaultBg; if (widget.decoration != null) { backgroundCol = null; } @@ -249,14 +253,16 @@ class CodeFieldState extends State { fontSize: textStyle.fontSize ?? 16.0, ); TextStyle numberTextStyle = widget.lineNumberStyle.textStyle ?? TextStyle(); - final numberColor = (theme?[ROOT_KEY]?.color ?? defaultText).withOpacity(0.7); + final numberColor = + (theme?[ROOT_KEY]?.color ?? defaultText).withOpacity(0.7); // Copy important attributes numberTextStyle = numberTextStyle.copyWith( color: numberTextStyle.color ?? numberColor, fontSize: textStyle.fontSize, fontFamily: textStyle.fontFamily, ); - final cursorColor = widget.cursorColor ?? theme?[ROOT_KEY]?.color ?? defaultText; + final cursorColor = + widget.cursorColor ?? theme?[ROOT_KEY]?.color ?? defaultText; final lineNumberCol = TextField( smartQuotesType: widget.smartQuotesType, @@ -315,7 +321,9 @@ class CodeFieldState extends State { child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { // Control horizontal scrolling - return widget.wrap ? codeField : _wrapInScrollView(codeField, textStyle, constraints.maxWidth); + return widget.wrap + ? codeField + : _wrapInScrollView(codeField, textStyle, constraints.maxWidth); }, ), ); diff --git a/pub/code_field-master/lib/src/code_modifier.dart b/pub/code_field-master/lib/src/code_modifier.dart index 6239033..fdf4f8b 100644 --- a/pub/code_field-master/lib/src/code_modifier.dart +++ b/pub/code_field-master/lib/src/code_modifier.dart @@ -19,7 +19,8 @@ abstract class CodeModifier { ); } - TextEditingValue? updateString(String text, TextSelection sel, EditorParams params); + TextEditingValue? updateString( + String text, TextSelection sel, EditorParams params); } class IntendModifier extends CodeModifier { @@ -30,7 +31,8 @@ class IntendModifier extends CodeModifier { }) : super('\n'); @override - TextEditingValue? updateString(String text, TextSelection sel, EditorParams params) { + TextEditingValue? updateString( + String text, TextSelection sel, EditorParams params) { var spacesCount = 0; var braceCount = 0; for (var k = min(sel.start, text.length) - 1; k >= 0; k--) { @@ -53,7 +55,8 @@ class CloseBlockModifier extends CodeModifier { const CloseBlockModifier() : super('}'); @override - TextEditingValue? updateString(String text, TextSelection sel, EditorParams params) { + TextEditingValue? updateString( + String text, TextSelection sel, EditorParams params) { int spaceCount = 0; for (var k = min(sel.start, text.length) - 1; k >= 0; k--) { if (text[k] == "\n") break; @@ -63,7 +66,8 @@ class CloseBlockModifier extends CodeModifier { } spaceCount += 1; } - if (spaceCount >= params.tabSpaces) return replace(text, sel.start - params.tabSpaces, sel.end, "}"); + if (spaceCount >= params.tabSpaces) + return replace(text, sel.start - params.tabSpaces, sel.end, "}"); return null; } } @@ -72,7 +76,8 @@ class TabModifier extends CodeModifier { const TabModifier() : super('\t'); @override - TextEditingValue? updateString(String text, TextSelection sel, EditorParams params) { + TextEditingValue? updateString( + String text, TextSelection sel, EditorParams params) { final tmp = replace(text, sel.start, sel.end, " " * params.tabSpaces); return tmp; } diff --git a/pubspec.lock b/pubspec.lock index 3f155ec..e2a3af9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -239,6 +239,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.1.2" + file_picker: + dependency: "direct main" + description: + name: file_picker + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.6.1" fixnum: dependency: transitive description: @@ -312,6 +319,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.6" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.6" flutter_riverpod: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 2a2d778..0f31f47 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,6 +37,7 @@ dependencies: share_plus: ^4.0.7 flutter_animator: ^3.2.1 modal_bottom_sheet: ^2.0.1 + file_picker: ^4.6.1 code_text_field: path: ./pub/code_field-master diff --git a/test/widget_test.dart b/test/widget_test.dart index baa5890..570e0e4 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -5,6 +5,4 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. -void main() { - -} +void main() {}