diff --git a/star_lock/lib/app.dart b/star_lock/lib/app.dart index 331ad5a6..63cbe964 100644 --- a/star_lock/lib/app.dart +++ b/star_lock/lib/app.dart @@ -57,7 +57,6 @@ class _MyAppState extends State with WidgetsBindingObserver, BaseWidget { locale = const Locale('zh', 'CN'); } } - // print("localelocalelocalelocalelocale locale:${locale} locale.languageCode:${locale.languageCode} locale.countryCode:${locale.countryCode} supportedLocales:${supportedLocales}"); AppManager() .setLanCode(code: '${locale!.languageCode}_${locale.countryCode}'); return locale; @@ -93,7 +92,8 @@ class _MyAppState extends State with WidgetsBindingObserver, BaseWidget { fontWeight: FontWeight.w400, fontSize: 36.sp), ), - splashColor: Colors.transparent, // 点击时的高亮效果设置为透明 + splashColor: Colors.transparent, + // 点击时的高亮效果设置为透明 highlightColor: Colors.transparent, ), debugShowCheckedModeBanner: false, diff --git a/star_lock/lib/debug/controller.dart b/star_lock/lib/debug/controller.dart new file mode 100644 index 00000000..176b0b59 --- /dev/null +++ b/star_lock/lib/debug/controller.dart @@ -0,0 +1,43 @@ +import 'dart:async'; + +import 'package:rxdart/rxdart.dart'; +import 'package:star_lock/debug/log.dart'; + + +class DebugConsoleController { + final List logs; + final _streamController = BehaviorSubject>(); + + DebugConsoleController({ List? logs }) : logs = logs ?? []; + + Stream> get stream => _streamController.stream; + + void close() => _streamController.close(); + void notifyUpdate() => _streamController.add(logs); + + void log( + Object? message, { + DebugConsoleLevel level = DebugConsoleLevel.normal, + DateTime? timestamp, + StackTrace? stackTrace, + }) { + logs.add( + DebugConsoleLog( + message: message, + level: level, + timestamp: timestamp, + stackTrace: stackTrace, + ) + ); + notifyUpdate(); + } + + List getLogsByLevel(DebugConsoleLevel level) { + return logs.where((log) => log.level == level).toList(); + } + + void clear() { + logs.clear(); + notifyUpdate(); + } +} \ No newline at end of file diff --git a/star_lock/lib/debug/debug_console.dart b/star_lock/lib/debug/debug_console.dart new file mode 100644 index 00000000..044cd085 --- /dev/null +++ b/star_lock/lib/debug/debug_console.dart @@ -0,0 +1,426 @@ +library debug_console; + +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/material.dart'; + +import 'package:star_lock/debug/controller.dart'; +import 'package:star_lock/debug/log.dart'; +import 'package:star_lock/debug/tile.dart'; +import 'package:star_lock/debug/utils/scrollable.dart'; + +/// # Debug Console +/// +/// A console for debugging Flutter apps, and displaying console messages on the widget. +/// +/// Check the console for prints and errors, while you're testing it, all within your app. Make your own logging or watch for console prints. +/// +/// ## Features +/// +/// * Log your messages +/// * Display console messages and errors +/// * Use different levels for better emphasis +/// * Filter the logs +/// * Add extra actions to execute from the Debug Console menu +/// * Check StackTrace of errors +class DebugConsole extends StatefulWidget { + final DebugConsoleController controller; + final List> actions; + + final bool expandStackTrace; + final String? savePath; + + /// # Debug Console + /// + /// A console for debugging Flutter apps, and displaying console messages on the widget. + /// + /// Check the console for prints and errors, while you're testing it, all within your app. Make your own logging or watch for console prints. + /// + /// ## Features + /// + /// * Log your messages + /// * Display console messages and errors + /// * Use different levels for better emphasis + /// * Filter the logs + /// * Add extra actions to execute from the Debug Console menu + /// * Check StackTrace of errors + DebugConsole({ + key, + DebugConsoleController? controller, + this.actions = const [], + this.expandStackTrace = false, + this.savePath, + }) : controller = controller ?? DebugConsole.instance; + + @override + State createState() => _DebugConsoleState(); + + static DebugConsoleController? _instance; + + static DebugConsoleController get instance { + _instance ??= DebugConsoleController( + logs: DebugConsoleLog.fromFile(DebugConsole.loadPath)); + return _instance!; + } + + static String loadPath = 'debug_console.log'; + + /// Adds a log to the root controller, attached with a message, level, timestamp and stack trace. + /// + /// The default level is `DebugConsoleLogLevel.normal`. + /// + /// Same as: + /// ```dart + /// DebugConsole.instance.log( ... ); + /// ``` + static void log( + Object? message, { + DebugConsoleLevel level = DebugConsoleLevel.normal, + DateTime? timestamp, + StackTrace? stackTrace, + }) => + instance.log( + message, + level: level, + timestamp: timestamp, + stackTrace: stackTrace, + ); + + /// Clears the logs of the root controller. + /// + /// Same as: + /// ```dart + /// DebugConsole.instance.clear(); + /// ``` + static void clear() => instance.clear(); + + /// Adds a log to the root controller, with the level `DebugConsoleLevel.info`. + /// + /// Same as: + /// ```dart + /// DebugConsole.log(message, level: DebugConsoleLevel.info, ... ); + /// ``` + static void info( + Object? message, { + DateTime? timestamp, + StackTrace? stackTrace, + }) => + log( + message, + level: DebugConsoleLevel.info, + timestamp: timestamp, + stackTrace: stackTrace, + ); + + /// Adds a log to the root controller, with the level `DebugConsoleLevel.warning`. + /// + /// Same as: + /// ```dart + /// DebugConsole.log(message, level: DebugConsoleLevel.warning, ... ); + /// ``` + static void warning( + Object? message, { + DateTime? timestamp, + StackTrace? stackTrace, + }) => + log( + message, + level: DebugConsoleLevel.warning, + timestamp: timestamp, + stackTrace: stackTrace, + ); + + /// Adds a log to the root controller, with the level `DebugConsoleLevel.error`. + /// + /// Same as: + /// ```dart + /// DebugConsole.log(message, level: DebugConsoleLevel.error, ... ); + /// ``` + static void error( + Object? message, { + DateTime? timestamp, + StackTrace? stackTrace, + }) => + log( + message, + level: DebugConsoleLevel.error, + timestamp: timestamp, + stackTrace: stackTrace, + ); + + /// Adds a log to the root controller, with the level `DebugConsoleLevel.fatal`. + /// + /// Same as: + /// ```dart + /// DebugConsole.log(message, level: DebugConsoleLevel.fatal, ... ); + /// ``` + static void fatal( + Object? message, { + DateTime? timestamp, + StackTrace? stackTrace, + }) => + log( + message, + level: DebugConsoleLevel.fatal, + timestamp: timestamp, + stackTrace: stackTrace, + ); + + /// Adds a log to the root controller, with the level `DebugConsoleLevel.debug`. + /// + /// Same as: + /// ```dart + /// DebugConsole.log(message, level: DebugConsoleLevel.debug, ... ); + /// ``` + static void debug( + Object? message, { + DateTime? timestamp, + StackTrace? stackTrace, + }) => + log( + message, + level: DebugConsoleLevel.debug, + timestamp: timestamp, + stackTrace: stackTrace, + ); + + /// Listen for prints and errors, to catch all messages in your app. + /// + /// Everything inside that function will be automatically logged. + /// + /// ```dart + /// DebugConsole.listen(() { + /// runApp(const MyApp()); + /// }); + /// ``` + /// + /// * A controller can be given, instead of logging to the root. + static void listen(void Function() body, + {DebugConsoleController? controller}) { + controller ??= DebugConsole.instance; + runZoned(body, + zoneSpecification: ZoneSpecification( + print: (Zone self, ZoneDelegate parent, Zone zone, String line) { + controller!.log(line); + parent.print(zone, line); + }, + handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, + Object error, StackTrace stackTrace) { + controller!.log(error, + level: DebugConsoleLevel.error, stackTrace: stackTrace); + parent.handleUncaughtError(zone, error, stackTrace); + }, + )); + } +} + +class _DebugConsoleState extends State { + StreamSubscription>? subscription; + List logs = []; + + bool expandStackTrace = false; + bool save = true; + String filter = ''; + + TextEditingController? textController; + + @override + void initState() { + super.initState(); + textController = TextEditingController(); + expandStackTrace = widget.expandStackTrace; + logs = widget.controller.logs; + subscription = widget.controller.stream.listen((logs) { + if (widget.savePath != null && save) saveToFile(logs: logs); + logs.sort((a, b) => a.timestamp.compareTo(b.timestamp)); + logs = logs.reversed.toList(); + setState(() => this.logs = logs); + }); + } + + @override + void dispose() { + subscription?.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final filteredLogs = filter.isEmpty + ? logs + : logs + .where((log) => filter.split(',').any((filter) { + filter = filter.trim(); + return filter.isNotEmpty && + log.message.toLowerCase().contains(filter.toLowerCase()); + })) + .toList(); + return Scaffold( + appBar: AppBar( + title: const Text('日志记录'), + actions: [ + PopupMenuButton( + icon: const Icon(Icons.more_vert), + itemBuilder: (context) => [ + ...widget.actions, + if (widget.actions.isNotEmpty) const PopupMenuDivider(), + PopupMenuItem( + child: StatefulBuilder( + builder: (context, setCheckboxState) => Row( + children: [ + const Expanded(child: Text('暂停日志记录')), + Checkbox( + value: subscription!.isPaused, + onChanged: (value) => + setCheckboxState(() => toggleLogging(!value!)), + ), + ], + ), + ), + onTap: () => toggleLogging(), + ), + PopupMenuItem( + child: StatefulBuilder( + builder: (context, setCheckboxState) => Row( + children: [ + const Expanded(child: Text('展开 StackTrace')), + Checkbox( + value: expandStackTrace, + onChanged: (value) => setCheckboxState( + () => setState(() => expandStackTrace = value!)), + ), + ], + ), + ), + onTap: () => + setState(() => expandStackTrace = !expandStackTrace), + ), + if (widget.savePath != null) + PopupMenuItem( + child: StatefulBuilder( + builder: (context, setCheckboxState) => Row( + children: [ + const Expanded(child: Text('保存')), + Checkbox( + value: save, + onChanged: (value) { + if (value!) saveToFile(); + setCheckboxState( + () => setState(() => save = value)); + }, + ), + ], + ), + ), + onTap: () { + if (!save) saveToFile(); + setState(() => save = !save); + }, + ), + PopupMenuItem( + onTap: () => widget.controller.clear(), + child: const Text('清除日志'), + ), + ], + ) + ], + ), + body: Stack( + children: [ + logs.isEmpty + ? const Padding( + padding: EdgeInsets.only(bottom: 50), + child: Center(child: Text('没有日志')), + ) + : ListView.builder( + padding: const EdgeInsets.only(bottom: 75), + reverse: true, + itemCount: filteredLogs.length, + itemBuilder: (context, index) { + final log = filteredLogs[index]; + return DebugConsoleTile(log, + key: ValueKey(log.timestamp), + expanded: expandStackTrace); + }, + ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( + margin: const EdgeInsets.all(15), + child: Row( + children: [ + Expanded( + child: TextField( + controller: textController, + decoration: InputDecoration( + filled: true, + fillColor: Colors.white, + contentPadding: + const EdgeInsets.symmetric(horizontal: 15), + hintText: 'Filter logs', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30), + ), + ), + onChanged: (value) => setState(() => filter = value), + ), + ), + const SizedBox(width: 5), + IconButton( + icon: const Icon(Icons.close), + onPressed: () { + textController!.clear(); + setState(() => filter = ''); + }, + ), + const SizedBox(width: 5), + FloatingActionButton( + tooltip: subscription!.isPaused + ? 'Resume logging' + : 'Pause logging', + onPressed: () => toggleLogging(), + child: Icon(subscription!.isPaused + ? Icons.play_arrow + : Icons.pause), + ), + ], + ), + ), + ), + ], + ), + ); + } + + void saveToFile({List? logs, String? path}) { + path ??= widget.savePath; + if (path == null) return; + logs ??= this.logs; + + logs.sort((a, b) => a.timestamp.compareTo(b.timestamp)); + logs = logs.reversed.toList(); + + final file = File(path); + if (logs.isEmpty) { + file.delete(); + } else { + file.writeAsString( + logs.map((log) => log.toString()).join('\n'), + ); + } + } + + void toggleLogging([bool? paused]) { + paused ??= subscription!.isPaused; + setState(() { + if (paused!) { + subscription!.resume(); + } else { + subscription!.pause(); + } + }); + } +} diff --git a/star_lock/lib/debug/debug_tool.dart b/star_lock/lib/debug/debug_tool.dart new file mode 100644 index 00000000..95e575ae --- /dev/null +++ b/star_lock/lib/debug/debug_tool.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/debug/controller.dart'; +import 'package:star_lock/debug/debug_console.dart'; + +class DeBug { + static void log(String message, {String? tag}) { + DebugConsole.info(message); + Get.log(message); + } + + static bool open = false; + static bool openInfo = false; + + static void showFloatWidget() { + Rx offset = Offset(20, 100).obs; // 初始位置 + OverlayEntry overlayEntry = OverlayEntry(builder: (context) { + return Obx(() => Positioned( + left: offset.value.dx, + top: offset.value.dy, + child: GestureDetector( + onPanUpdate: (details) { + offset.value += details.delta; + }, + child: FloatingActionButton( + child: Icon(Icons.bug_report), + onPressed: () { + if (openInfo) { + Get.back(); + return; + } + if (open) { + open = false; + Get.back(); + } else { + open = true; + Get.to(WillPopScope( + onWillPop: () async { + open = false; + return true; + }, + child: DebugConsole( + controller: DebugConsole.instance, + actions: [], + expandStackTrace: false, + savePath: null, + ), + )); + } + }, + ), + ))); + }); + Get.key.currentState?.overlay?.insert(overlayEntry); + } + + DeBug(); +} diff --git a/star_lock/lib/debug/log.dart b/star_lock/lib/debug/log.dart new file mode 100644 index 00000000..a46b03ad --- /dev/null +++ b/star_lock/lib/debug/log.dart @@ -0,0 +1,92 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; + +class DebugConsoleLog { + /// Message of the log. + final String message; + + /// Log level, used to determine the color and importance of the log. + final DebugConsoleLevel level; + + /// Time of when the log was created. + final DateTime timestamp; + + final StackTrace? stackTrace; + + DebugConsoleLog({ + Object? message, + this.level = DebugConsoleLevel.normal, + DateTime? timestamp, + this.stackTrace, + }) : message = '$message', + timestamp = timestamp ?? DateTime.now(); + + @override + String toString() { + return '[$level] $timestamp\n$message\n---${stackTrace != null ? ':' : ''}\n${stackTrace != null ? '${stackTrace ?? ''}---\n' : ''}'; + } + + static List fromFile(String filePath) { + final List logs = []; + + final File file = File(filePath); + if (!file.existsSync()) return logs; + + final RegExp regex = RegExp( + r'\[(?.*)\] (?.*)\n(?(?:.|\n)*?)\n---(?::\n(?(?:.|\n)*?)---\n)?', + multiLine: true, + ); + final matches = regex.allMatches(file.readAsStringSync()); + for (final match in matches) { + final String level = match.namedGroup('level') ?? 'normal'; + final String timestamp = match.namedGroup('timestamp') ?? ''; + final String message = match.namedGroup('message') ?? ''; + final String stackTrace = match.namedGroup('stackTrace') ?? ''; + + logs.add(DebugConsoleLog( + message: message, + level: DebugConsoleLevel.values.firstWhere( + (DebugConsoleLevel findingLevel) => + level.toString() == findingLevel.toString(), + orElse: () => DebugConsoleLevel.normal, + ), + timestamp: DateTime.parse(timestamp), + stackTrace: + stackTrace.isNotEmpty ? StackTrace.fromString(stackTrace) : null, + )); + } + + return logs; + } +} + +class DebugConsoleLevel { + static const DebugConsoleLevel normal = DebugConsoleLevel('Normal'); + static const DebugConsoleLevel info = + DebugConsoleLevel('Info', Colors.lightBlueAccent); + static const DebugConsoleLevel warning = + DebugConsoleLevel('Warning', Colors.deepOrange); + static const DebugConsoleLevel error = + DebugConsoleLevel('Error', Colors.redAccent); + static const DebugConsoleLevel fatal = DebugConsoleLevel('Fatal', Colors.red); + static const DebugConsoleLevel debug = + DebugConsoleLevel('Debug', Colors.blue); + + static const List values = [ + normal, + info, + warning, + error, + fatal, + debug, + ]; + + final String name; + final Color? color; + + const DebugConsoleLevel(this.name, [this.color]); + + @override + String toString() => name; +} diff --git a/star_lock/lib/debug/popup.dart b/star_lock/lib/debug/popup.dart new file mode 100644 index 00000000..a50f1f9a --- /dev/null +++ b/star_lock/lib/debug/popup.dart @@ -0,0 +1,81 @@ + +import 'package:flutter/material.dart'; +import 'package:star_lock/debug/controller.dart'; +import 'package:star_lock/debug/debug_console.dart'; + +/// A widget that adds a floating button for debugging purposes. +class DebugConsolePopup extends StatefulWidget { + final Widget child; + + final bool showButton; + + final DebugConsoleController controller; + final List> actions; + final bool expandStackTrace; + final String? savePath; + + DebugConsolePopup({ + key, + required this.child, + + this.showButton = true, + + DebugConsoleController? controller, + this.actions = const [], + this.expandStackTrace = false, + this.savePath, + }) : + controller = controller ?? DebugConsole.instance; + + @override + State createState() => _DebugConsolePopupState(); +} + +class _DebugConsolePopupState extends State { + bool isOpen = false; + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + widget.child, + if (widget.showButton) + Positioned( + right: 15, + bottom: 15, + child: FloatingActionButton( + child: const Icon(Icons.bug_report), + onPressed: () => popup(true), + ), + ), + ], + ); + } + + void popup([ bool? open ]) { + open ??= !isOpen; + if (open == isOpen) return; + if (open) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => WillPopScope( + onWillPop: () async { + isOpen = false; + return true; + }, + child: DebugConsole( + controller: widget.controller, + actions: widget.actions, + expandStackTrace: widget.expandStackTrace, + savePath: widget.savePath, + ), + ), + ), + ); + } else { + Navigator.pop(context); + } + isOpen = open; + } +} \ No newline at end of file diff --git a/star_lock/lib/debug/tile.dart b/star_lock/lib/debug/tile.dart new file mode 100644 index 00000000..a23cd98a --- /dev/null +++ b/star_lock/lib/debug/tile.dart @@ -0,0 +1,134 @@ +import 'package:expandable/expandable.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:star_lock/debug/debug_tool.dart'; +import 'package:star_lock/debug/log.dart'; + +class DebugConsoleTile extends StatefulWidget { + final DebugConsoleLog log; + final bool expanded; + + const DebugConsoleTile(this.log, {key, this.expanded = false}); + + @override + State createState() => _DebugConsoleTileState(); +} + +class _DebugConsoleTileState extends State { + ExpandableController? controller; + + @override + void initState() { + super.initState(); + controller = ExpandableController(initialExpanded: widget.expanded); + } + + @override + Widget build(BuildContext context) { + return Container( + color: widget.log.level.color?.withOpacity(0.05), + child: Container( + color: widget.log.level.color?.withOpacity(0.05), + child: InkWell( + onTap: widget.log.stackTrace != null + ? () { + controller!.toggle(); + setState(() {}); + } + : () async { + DeBug.openInfo = true; + await Get.to(DeBugText(widget.log)); + DeBug.openInfo = false; + }, + child: ExpandablePanel( + controller: controller, + theme: const ExpandableThemeData( + tapBodyToCollapse: false, + tapHeaderToExpand: false, + hasIcon: false, + ), + header: ListTile( + textColor: widget.log.level.color, + title: Text( + widget.log.message, + maxLines: 5, + overflow: TextOverflow.ellipsis, + ), + trailing: Column( + children: [ + SizedBox(height: widget.log.stackTrace != null ? 4 : 15), + Opacity( + opacity: 0.5, + child: widget.log.timestamp + .difference(DateTime.now()) + .inDays > + 1 + ? Text( + '${widget.log.timestamp.toIso8601String().substring(0, 10)} ${widget.log.timestamp.toIso8601String().substring(11, 19)}') + : Text(widget.log.timestamp + .toIso8601String() + .substring(11, 19)), + ), + if (widget.log.stackTrace != null) + AnimatedRotation( + duration: const Duration(milliseconds: 200), + curve: Curves.easeInOut, + turns: controller!.expanded ? -0.5 : 0, + child: Icon(Icons.keyboard_arrow_down, + color: widget.log.level.color), + ) + ], + ), + ), + collapsed: Container(), + expanded: widget.log.stackTrace != null + ? Opacity( + opacity: 0.75, + child: ListTile( + textColor: widget.log.level.color, + title: Text(widget.log.stackTrace.toString()), + ), + ) + : Container(), + ), + ), + ), + ); + } +} + +class DeBugText extends StatefulWidget { + final DebugConsoleLog log; + + DeBugText(this.log, {key}); + + @override + State createState() => _DeBugTextState(); +} + +class _DeBugTextState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('详细日志'), + ), + body: SafeArea( + child: GestureDetector( + onTap: () { + Clipboard.setData(ClipboardData(text: widget.log.message)); + EasyLoading.showToast('已复制到剪切板'); + }, + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(18.w), + child: Text(widget.log.message), + )), + ), + ), + ); + } +} diff --git a/star_lock/lib/debug/utils/scrollable.dart b/star_lock/lib/debug/utils/scrollable.dart new file mode 100644 index 00000000..105bd90a --- /dev/null +++ b/star_lock/lib/debug/utils/scrollable.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +// https://github.com/flutter/flutter/issues/63946#issuecomment-1000442747 +// - By: https://github.com/PaulBout1 + +class AllwaysScrollableFixedPositionScrollPhysics extends ScrollPhysics { + const AllwaysScrollableFixedPositionScrollPhysics({ScrollPhysics? parent}) + : super(parent: parent); + + @override + AllwaysScrollableFixedPositionScrollPhysics applyTo(ScrollPhysics? ancestor) { + return AllwaysScrollableFixedPositionScrollPhysics(parent: buildParent(ancestor)); + } + + @override + double adjustPositionForNewDimensions({ + required ScrollMetrics oldPosition, + required ScrollMetrics newPosition, + required bool isScrolling, + required double velocity, + }) { + if (newPosition.extentBefore == 0) { + return super.adjustPositionForNewDimensions( + oldPosition: oldPosition, + newPosition: newPosition, + isScrolling: isScrolling, + velocity: velocity, + ); + } + return newPosition.maxScrollExtent - oldPosition.extentAfter; + } + + @override + bool shouldAcceptUserOffset(ScrollMetrics position) => true; +} \ No newline at end of file diff --git a/star_lock/lib/flavors.dart b/star_lock/lib/flavors.dart index 0edae29a..cfb882c4 100644 --- a/star_lock/lib/flavors.dart +++ b/star_lock/lib/flavors.dart @@ -26,6 +26,23 @@ class F { static String get name => appFlavor?.name ?? ''; + static bool get debug { + switch (appFlavor) { + case Flavor.local: + return true; + case Flavor.dev: + return true; + case Flavor.pre: + return true; + case Flavor.sky: + return false; + case Flavor.xhj: + return false; + default: + return false; + } + } + static String get title { switch (appFlavor) { case Flavor.local: @@ -85,13 +102,16 @@ class F { case Flavor.local: case Flavor.dev: return const StarLockAMapKey( - androidKey: 'b56b681ee89f4db43a5aa1879ae8cbfe', iosKey: 'bd4496e6598ef49796e3a80715035b4d'); + androidKey: 'b56b681ee89f4db43a5aa1879ae8cbfe', + iosKey: 'bd4496e6598ef49796e3a80715035b4d'); case Flavor.pre: return const StarLockAMapKey( - androidKey: '11d49b3f4fc09c04a02bbb7500925ba2', iosKey: '883a3355d2d77c2fdc2667030dc97ffe'); + androidKey: '11d49b3f4fc09c04a02bbb7500925ba2', + iosKey: '883a3355d2d77c2fdc2667030dc97ffe'); case Flavor.sky: return const StarLockAMapKey( - androidKey: 'fb0d2a3e4208b36452cf636aa025a24f', iosKey: '86ca725a12a629c280e116a317aaba19'); + androidKey: 'fb0d2a3e4208b36452cf636aa025a24f', + iosKey: '86ca725a12a629c280e116a317aaba19'); // case Flavor.xhj: // return const StarLockAMapKey( // androidKey: 'todo', diff --git a/star_lock/lib/main.dart b/star_lock/lib/main.dart index 0b999875..6e111af5 100644 --- a/star_lock/lib/main.dart +++ b/star_lock/lib/main.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:star_lock/debug/debug_console.dart'; import 'package:star_lock/flavors.dart'; import 'package:star_lock/translations/trans_lib.dart'; import 'app.dart'; @@ -17,7 +18,13 @@ FutureOr main() async { // 设置国际化信息 await _initTranslation(); - runApp(MyApp()); + if(F.debug){ + DebugConsole.listen(() { + runApp(const MyApp()); + }); + }else{ + runApp(const MyApp()); + } if (AppPlatform.isAndroid) { SystemUiOverlayStyle systemUiOverlayStyle = diff --git a/star_lock/lib/network/request_interceptor_log.dart b/star_lock/lib/network/request_interceptor_log.dart index 5b5fe430..030ca78b 100644 --- a/star_lock/lib/network/request_interceptor_log.dart +++ b/star_lock/lib/network/request_interceptor_log.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; import 'package:get/get_connect/http/src/request/request.dart'; +import 'package:star_lock/debug/log.dart'; FutureOr requestLogInterceptor(Request request) async { Get.log( diff --git a/star_lock/lib/starLockApplication/starLockApplication.dart b/star_lock/lib/starLockApplication/starLockApplication.dart index 3bbce837..25182df5 100644 --- a/star_lock/lib/starLockApplication/starLockApplication.dart +++ b/star_lock/lib/starLockApplication/starLockApplication.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:star_lock/login/login/starLock_login_page.dart'; import 'package:star_lock/tools/appFirstEnterHandle.dart'; +import 'package:star_lock/debug/debug_tool.dart'; import 'package:star_lock/tools/storage.dart'; import '../main/lockMian/lockMain/lockMain_page.dart'; @@ -15,9 +17,11 @@ class StarLockApplication extends StatefulWidget { class _StarLockApplicationState extends State { @override void initState() { - // TODO: implement initState super.initState(); print("StarLockApplication initState"); + WidgetsBinding.instance.addPostFrameCallback((_) { + DeBug.showFloatWidget(); + }); } @override diff --git a/star_lock/pubspec.yaml b/star_lock/pubspec.yaml index f6764a7b..6ee6748b 100644 --- a/star_lock/pubspec.yaml +++ b/star_lock/pubspec.yaml @@ -29,8 +29,11 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # 1.0.24+20240407:1、打包预发布环境给欧阳测试 # 1.0.25+2024040702:1、打包预发布环境给欧阳测试 # 1.0.26+20240408:打包预发布环境给欧阳测试 +# 1.0.27+2024041101:打包提审 +# 1.0.27+2024041102:打包预发布环境给田总测试 -version: 1.0.26+20240408 + +version: 1.0.27+2024041102 environment: sdk: '>=2.12.0 <3.0.0' @@ -156,8 +159,10 @@ dependencies: app_settings: ^5.1.1 flutter_local_notifications: ^17.0.0 fluwx: ^4.5.5 - system_settings: ^2.0.0 + expandable: ^5.0.1 + + dev_dependencies: flutter_test: sdk: flutter