diff --git a/assets/icon/bottom_nav_home_select.png b/assets/icon/bottom_nav_home_select.png new file mode 100644 index 0000000..efbbc84 Binary files /dev/null and b/assets/icon/bottom_nav_home_select.png differ diff --git a/assets/icon/bottom_nav_home_unselect.gif b/assets/icon/bottom_nav_home_unselect.gif new file mode 100644 index 0000000..5cd5afc Binary files /dev/null and b/assets/icon/bottom_nav_home_unselect.gif differ diff --git a/assets/icon/bottom_nav_profile_select.png b/assets/icon/bottom_nav_profile_select.png new file mode 100644 index 0000000..f98e580 Binary files /dev/null and b/assets/icon/bottom_nav_profile_select.png differ diff --git a/assets/icon/bottom_nav_profile_unselect.png b/assets/icon/bottom_nav_profile_unselect.png new file mode 100644 index 0000000..b2d50f3 Binary files /dev/null and b/assets/icon/bottom_nav_profile_unselect.png differ diff --git a/assets/icon/bottom_nav_sleep_select.png b/assets/icon/bottom_nav_sleep_select.png new file mode 100644 index 0000000..c33b00c Binary files /dev/null and b/assets/icon/bottom_nav_sleep_select.png differ diff --git a/assets/icon/bottom_nav_sleep_unselect.png b/assets/icon/bottom_nav_sleep_unselect.png new file mode 100644 index 0000000..7f0d380 Binary files /dev/null and b/assets/icon/bottom_nav_sleep_unselect.png differ diff --git a/assets/icon/home_ai_model.png b/assets/icon/home_ai_model.png new file mode 100644 index 0000000..8f39a88 Binary files /dev/null and b/assets/icon/home_ai_model.png differ diff --git a/assets/icon/home_bluetooth.png b/assets/icon/home_bluetooth.png new file mode 100644 index 0000000..c4f7e68 Binary files /dev/null and b/assets/icon/home_bluetooth.png differ diff --git a/assets/icon/home_icon_fyjl.png b/assets/icon/home_icon_fyjl.png new file mode 100644 index 0000000..c7c0891 Binary files /dev/null and b/assets/icon/home_icon_fyjl.png differ diff --git a/assets/icon/home_icon_mdmfy.png b/assets/icon/home_icon_mdmfy.png new file mode 100644 index 0000000..ad9ed49 Binary files /dev/null and b/assets/icon/home_icon_mdmfy.png differ diff --git a/assets/icon/home_icon_tcty.png b/assets/icon/home_icon_tcty.png new file mode 100644 index 0000000..8770de1 Binary files /dev/null and b/assets/icon/home_icon_tcty.png differ diff --git a/assets/icon/home_icon_thyyfy.png b/assets/icon/home_icon_thyyfy.png new file mode 100644 index 0000000..a56597a Binary files /dev/null and b/assets/icon/home_icon_thyyfy.png differ diff --git a/assets/icon/home_img.png b/assets/icon/home_img.png new file mode 100644 index 0000000..f3c946a Binary files /dev/null and b/assets/icon/home_img.png differ diff --git a/assets/icon/home_question.png b/assets/icon/home_question.png new file mode 100644 index 0000000..ea06918 Binary files /dev/null and b/assets/icon/home_question.png differ diff --git a/assets/icon/icon.png b/assets/icon/icon.png new file mode 100644 index 0000000..1374182 Binary files /dev/null and b/assets/icon/icon.png differ diff --git a/assets/img/image_ai.png b/assets/img/image_ai.png new file mode 100644 index 0000000..1b20c2e Binary files /dev/null and b/assets/img/image_ai.png differ diff --git a/assets/img/image_bg_blur.png b/assets/img/image_bg_blur.png new file mode 100644 index 0000000..48eea0c Binary files /dev/null and b/assets/img/image_bg_blur.png differ diff --git a/assets/img/image_user.png b/assets/img/image_user.png new file mode 100644 index 0000000..db3b041 Binary files /dev/null and b/assets/img/image_user.png differ diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart new file mode 100644 index 0000000..af78d38 --- /dev/null +++ b/lib/gen/assets.gen.dart @@ -0,0 +1,197 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use + +import 'package:flutter/widgets.dart'; + +class $AssetsIconGen { + const $AssetsIconGen(); + + /// File path: assets/icon/bottom_nav_home_select.png + AssetGenImage get bottomNavHomeSelect => + const AssetGenImage('assets/icon/bottom_nav_home_select.png'); + + /// File path: assets/icon/bottom_nav_home_unselect.gif + AssetGenImage get bottomNavHomeUnselect => + const AssetGenImage('assets/icon/bottom_nav_home_unselect.gif'); + + /// File path: assets/icon/bottom_nav_profile_select.png + AssetGenImage get bottomNavProfileSelect => + const AssetGenImage('assets/icon/bottom_nav_profile_select.png'); + + /// File path: assets/icon/bottom_nav_profile_unselect.png + AssetGenImage get bottomNavProfileUnselect => + const AssetGenImage('assets/icon/bottom_nav_profile_unselect.png'); + + /// File path: assets/icon/bottom_nav_sleep_select.png + AssetGenImage get bottomNavSleepSelect => + const AssetGenImage('assets/icon/bottom_nav_sleep_select.png'); + + /// File path: assets/icon/bottom_nav_sleep_unselect.png + AssetGenImage get bottomNavSleepUnselect => + const AssetGenImage('assets/icon/bottom_nav_sleep_unselect.png'); + + /// File path: assets/icon/home_ai_model.png + AssetGenImage get homeAiModel => + const AssetGenImage('assets/icon/home_ai_model.png'); + + /// File path: assets/icon/home_bluetooth.png + AssetGenImage get homeBluetooth => + const AssetGenImage('assets/icon/home_bluetooth.png'); + + /// File path: assets/icon/home_icon_fyjl.png + AssetGenImage get homeIconFyjl => + const AssetGenImage('assets/icon/home_icon_fyjl.png'); + + /// File path: assets/icon/home_icon_mdmfy.png + AssetGenImage get homeIconMdmfy => + const AssetGenImage('assets/icon/home_icon_mdmfy.png'); + + /// File path: assets/icon/home_icon_tcty.png + AssetGenImage get homeIconTcty => + const AssetGenImage('assets/icon/home_icon_tcty.png'); + + /// File path: assets/icon/home_icon_thyyfy.png + AssetGenImage get homeIconThyyfy => + const AssetGenImage('assets/icon/home_icon_thyyfy.png'); + + /// File path: assets/icon/home_img.png + AssetGenImage get homeImg => const AssetGenImage('assets/icon/home_img.png'); + + /// File path: assets/icon/home_question.png + AssetGenImage get homeQuestion => + const AssetGenImage('assets/icon/home_question.png'); + + /// File path: assets/icon/icon.png + AssetGenImage get icon => const AssetGenImage('assets/icon/icon.png'); + + /// List of all assets + List get values => [ + bottomNavHomeSelect, + bottomNavHomeUnselect, + bottomNavProfileSelect, + bottomNavProfileUnselect, + bottomNavSleepSelect, + bottomNavSleepUnselect, + homeAiModel, + homeBluetooth, + homeIconFyjl, + homeIconMdmfy, + homeIconTcty, + homeIconThyyfy, + homeImg, + homeQuestion, + icon + ]; +} + +class $AssetsImgGen { + const $AssetsImgGen(); + + /// File path: assets/img/image_ai.png + AssetGenImage get imageAi => const AssetGenImage('assets/img/image_ai.png'); + + /// File path: assets/img/image_bg_blur.png + AssetGenImage get imageBgBlur => + const AssetGenImage('assets/img/image_bg_blur.png'); + + /// File path: assets/img/image_user.png + AssetGenImage get imageUser => + const AssetGenImage('assets/img/image_user.png'); + + /// List of all assets + List get values => [imageAi, imageBgBlur, imageUser]; +} + +class Assets { + const Assets._(); + + static const $AssetsIconGen icon = $AssetsIconGen(); + static const $AssetsImgGen img = $AssetsImgGen(); +} + +class AssetGenImage { + const AssetGenImage( + this._assetName, { + this.size, + this.flavors = const {}, + }); + + final String _assetName; + + final Size? size; + final Set flavors; + + Image image({ + Key? key, + AssetBundle? bundle, + ImageFrameBuilder? frameBuilder, + ImageErrorWidgetBuilder? errorBuilder, + String? semanticLabel, + bool excludeFromSemantics = false, + double? scale, + double? width, + double? height, + Color? color, + Animation? opacity, + BlendMode? colorBlendMode, + BoxFit? fit, + AlignmentGeometry alignment = Alignment.center, + ImageRepeat repeat = ImageRepeat.noRepeat, + Rect? centerSlice, + bool matchTextDirection = false, + bool gaplessPlayback = true, + bool isAntiAlias = false, + String? package, + FilterQuality filterQuality = FilterQuality.medium, + int? cacheWidth, + int? cacheHeight, + }) { + return Image.asset( + _assetName, + key: key, + bundle: bundle, + frameBuilder: frameBuilder, + errorBuilder: errorBuilder, + semanticLabel: semanticLabel, + excludeFromSemantics: excludeFromSemantics, + scale: scale, + width: width, + height: height, + color: color, + opacity: opacity, + colorBlendMode: colorBlendMode, + fit: fit, + alignment: alignment, + repeat: repeat, + centerSlice: centerSlice, + matchTextDirection: matchTextDirection, + gaplessPlayback: gaplessPlayback, + isAntiAlias: isAntiAlias, + package: package, + filterQuality: filterQuality, + cacheWidth: cacheWidth, + cacheHeight: cacheHeight, + ); + } + + ImageProvider provider({ + AssetBundle? bundle, + String? package, + }) { + return AssetImage( + _assetName, + bundle: bundle, + package: package, + ); + } + + String get path => _assetName; + + String get keyName => _assetName; +} diff --git a/lib/generated/intl/messages_all.dart b/lib/generated/intl/messages_all.dart new file mode 100644 index 0000000..32161b6 --- /dev/null +++ b/lib/generated/intl/messages_all.dart @@ -0,0 +1,67 @@ +// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart +// This is a library that looks up messages for specific locales by +// delegating to the appropriate library. + +// Ignore issues from commonly used lints in this file. +// ignore_for_file:implementation_imports, file_names, unnecessary_new +// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering +// ignore_for_file:argument_type_not_assignable, invalid_assignment +// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases +// ignore_for_file:comment_references + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:intl/intl.dart'; +import 'package:intl/message_lookup_by_library.dart'; +import 'package:intl/src/intl_helpers.dart'; + +import 'messages_en.dart' as messages_en; +import 'messages_zh.dart' as messages_zh; + +typedef Future LibraryLoader(); +Map _deferredLibraries = { + 'en': () => new SynchronousFuture(null), + 'zh': () => new SynchronousFuture(null), +}; + +MessageLookupByLibrary? _findExact(String localeName) { + switch (localeName) { + case 'en': + return messages_en.messages; + case 'zh': + return messages_zh.messages; + default: + return null; + } +} + +/// User programs should call this before using [localeName] for messages. +Future initializeMessages(String localeName) { + var availableLocale = Intl.verifiedLocale( + localeName, (locale) => _deferredLibraries[locale] != null, + onFailure: (_) => null); + if (availableLocale == null) { + return new SynchronousFuture(false); + } + var lib = _deferredLibraries[availableLocale]; + lib == null ? new SynchronousFuture(false) : lib(); + initializeInternalMessageLookup(() => new CompositeMessageLookup()); + messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor); + return new SynchronousFuture(true); +} + +bool _messagesExistFor(String locale) { + try { + return _findExact(locale) != null; + } catch (e) { + return false; + } +} + +MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) { + var actualLocale = + Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null); + if (actualLocale == null) return null; + return _findExact(actualLocale); +} diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart new file mode 100644 index 0000000..fb27c38 --- /dev/null +++ b/lib/generated/intl/messages_en.dart @@ -0,0 +1,29 @@ +// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart +// This is a library that provides messages for a en locale. All the +// messages from the main program should be duplicated here with the same +// function name. + +// Ignore issues from commonly used lints in this file. +// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new +// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering +// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases +// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes +// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes + +import 'package:intl/intl.dart'; +import 'package:intl/message_lookup_by_library.dart'; + +final messages = new MessageLookup(); + +typedef String MessageIfAbsent(String messageStr, List args); + +class MessageLookup extends MessageLookupByLibrary { + String get localeName => 'en'; + + final messages = _notInlinedMessages(_notInlinedMessages); + static Map _notInlinedMessages(_) => { + "bottomNavHome": MessageLookupByLibrary.simpleMessage("home"), + "bottomNavProfile": MessageLookupByLibrary.simpleMessage("profile"), + "bottomNavSleep": MessageLookupByLibrary.simpleMessage("sleep") + }; +} diff --git a/lib/generated/intl/messages_zh.dart b/lib/generated/intl/messages_zh.dart new file mode 100644 index 0000000..d5fb763 --- /dev/null +++ b/lib/generated/intl/messages_zh.dart @@ -0,0 +1,29 @@ +// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart +// This is a library that provides messages for a zh locale. All the +// messages from the main program should be duplicated here with the same +// function name. + +// Ignore issues from commonly used lints in this file. +// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new +// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering +// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases +// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes +// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes + +import 'package:intl/intl.dart'; +import 'package:intl/message_lookup_by_library.dart'; + +final messages = new MessageLookup(); + +typedef String MessageIfAbsent(String messageStr, List args); + +class MessageLookup extends MessageLookupByLibrary { + String get localeName => 'zh'; + + final messages = _notInlinedMessages(_notInlinedMessages); + static Map _notInlinedMessages(_) => { + "bottomNavHome": MessageLookupByLibrary.simpleMessage("首页"), + "bottomNavProfile": MessageLookupByLibrary.simpleMessage("我的"), + "bottomNavSleep": MessageLookupByLibrary.simpleMessage("睡眠") + }; +} diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart new file mode 100644 index 0000000..c5b7706 --- /dev/null +++ b/lib/generated/l10n.dart @@ -0,0 +1,109 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'intl/messages_all.dart'; + +// ************************************************************************** +// Generator: Flutter Intl IDE plugin +// Made by Localizely +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, lines_longer_than_80_chars +// ignore_for_file: join_return_with_assignment, prefer_final_in_for_each +// ignore_for_file: avoid_redundant_argument_values, avoid_escaping_inner_quotes + +class S { + S(); + + static S? _current; + + static S get current { + assert(_current != null, + 'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.'); + return _current!; + } + + static const AppLocalizationDelegate delegate = AppLocalizationDelegate(); + + static Future load(Locale locale) { + final name = (locale.countryCode?.isEmpty ?? false) + ? locale.languageCode + : locale.toString(); + final localeName = Intl.canonicalizedLocale(name); + return initializeMessages(localeName).then((_) { + Intl.defaultLocale = localeName; + final instance = S(); + S._current = instance; + + return instance; + }); + } + + static S of(BuildContext context) { + final instance = S.maybeOf(context); + assert(instance != null, + 'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?'); + return instance!; + } + + static S? maybeOf(BuildContext context) { + return Localizations.of(context, S); + } + + /// `home` + String get bottomNavHome { + return Intl.message( + 'home', + name: 'bottomNavHome', + desc: '', + args: [], + ); + } + + /// `sleep` + String get bottomNavSleep { + return Intl.message( + 'sleep', + name: 'bottomNavSleep', + desc: '', + args: [], + ); + } + + /// `profile` + String get bottomNavProfile { + return Intl.message( + 'profile', + name: 'bottomNavProfile', + desc: '', + args: [], + ); + } +} + +class AppLocalizationDelegate extends LocalizationsDelegate { + const AppLocalizationDelegate(); + + List get supportedLocales { + return const [ + Locale.fromSubtags(languageCode: 'en'), + Locale.fromSubtags(languageCode: 'zh'), + ]; + } + + @override + bool isSupported(Locale locale) => _isSupported(locale); + @override + Future load(Locale locale) => S.load(locale); + @override + bool shouldReload(AppLocalizationDelegate old) => false; + + bool _isSupported(Locale locale) { + for (var supportedLocale in supportedLocales) { + if (supportedLocale.languageCode == locale.languageCode) { + return true; + } + } + return false; + } +} diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb new file mode 100644 index 0000000..a09997c --- /dev/null +++ b/lib/l10n/intl_en.arb @@ -0,0 +1,6 @@ +{ + "@@locale": "en", + "bottomNavHome": "home", + "bottomNavSleep": "sleep", + "bottomNavProfile": "profile" +} \ No newline at end of file diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb new file mode 100644 index 0000000..a30c2bb --- /dev/null +++ b/lib/l10n/intl_zh.arb @@ -0,0 +1,6 @@ +{ + "@@locale": "zh", + "bottomNavHome": "首页", + "bottomNavSleep": "睡眠", + "bottomNavProfile": "我的" +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index af85ea3..012681c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,27 @@ +import 'package:demo001/gen/assets.gen.dart'; +import 'package:demo001/generated/l10n.dart'; +import 'package:demo001/scenes/home/home_view.dart'; import 'package:demo001/scenes/translate/TranslateScene.dart'; +import 'package:demo001/tools/color_utils.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:get/get.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; + +import 'scenes/login/login_view.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); + EasyLoading.instance + ..indicatorType = EasyLoadingIndicatorType.threeBounce + ..maskType = EasyLoadingMaskType.black + ..progressColor = Colors.white + ..backgroundColor = const Color.fromRGBO(38, 38, 38, 1) + ..indicatorColor = Colors.white + ..textColor = Colors.white + ..userInteractions = false + ..displayDuration = 1.5.seconds + ..dismissOnTap = false; runApp(const MyApp()); } @@ -12,13 +31,107 @@ class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', + return GetMaterialApp( + locale: Get.deviceLocale, + fallbackLocale: Get.deviceLocale, + title: '智能耳机', + debugShowCheckedModeBanner: false, + defaultTransition: Transition.rightToLeft, theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, - ), - home: TranslateScene(), + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + appBarTheme: const AppBarTheme( + centerTitle: true, + iconTheme: IconThemeData(color: whiteGrey), + surfaceTintColor: white, + shape: Border(bottom: BorderSide(color: lightBlue, width: 1)), + backgroundColor: bgColor, + ), + scaffoldBackgroundColor: bgColor, + splashColor: clean, + highlightColor: clean, + switchTheme: SwitchThemeData( + trackOutlineColor: const WidgetStatePropertyAll(blue), + trackColor: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.selected)) { + return blue; + } else { + return silver.withOpacity(0.5); + } + }), + thumbColor: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.selected)) { + return white; + } else { + return silver; + } + }), + trackOutlineWidth: const WidgetStatePropertyAll(0)), + navigationBarTheme: NavigationBarThemeData()), + localizationsDelegates: { + S.delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + }, + supportedLocales: S.delegate.supportedLocales, + home: LoginScene(), + builder: (context, widget) { + final easyload = EasyLoading.init(); + var child = easyload(context, widget); + return MediaQuery( + data: + MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling), + child: child, + ); + }, ); } } + +S? s; + +class IndexWidget extends StatelessWidget { + final RxInt _currentIndex = 0.obs; + + final List _pages = [HomePage()]; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Obx(() => _pages[_currentIndex.value]), + bottomNavigationBar: Builder(builder: (context) { + s = S.of(context); + return Obx(() => BottomNavigationBar( + type: BottomNavigationBarType.fixed, + backgroundColor: bottomNavBg, + currentIndex: _currentIndex.value, + selectedItemColor: white, + unselectedItemColor: grey, + items: [ + BottomNavigationBarItem( + icon: Assets.icon.bottomNavHomeUnselect + .image(width: 20, height: 20), + activeIcon: Assets.icon.bottomNavHomeSelect + .image(width: 20, height: 20), + label: s?.bottomNavHome), + BottomNavigationBarItem( + icon: Assets.icon.bottomNavSleepUnselect + .image(width: 20, height: 20), + activeIcon: Assets.icon.bottomNavSleepSelect + .image(width: 20, height: 20), + label: s?.bottomNavSleep), + BottomNavigationBarItem( + icon: Assets.icon.bottomNavProfileUnselect + .image(width: 20, height: 20), + activeIcon: Assets.icon.bottomNavProfileSelect + .image(width: 20, height: 20), + label: s?.bottomNavProfile), + ], + onTap: (index) { + _currentIndex.value = index; + }, + )); + })); + } +} diff --git a/lib/scenes/AIChatScene.dart b/lib/scenes/AIChatScene.dart deleted file mode 100644 index c7f8ce9..0000000 --- a/lib/scenes/AIChatScene.dart +++ /dev/null @@ -1,129 +0,0 @@ -/* - AI测试场景 -*/ -import 'package:flutter/material.dart'; -import 'package:demo001/doubao/DouBao.dart'; - -class ChatItem { - String msg = ""; - int state = 0; - - ChatItem({required this.msg}); - - void append(String _msg) { - msg += _msg; - } - - void end() { - state = 1; - } -} - -class AIChatScene extends StatefulWidget { - @override - _AIChatSceneState createState() => _AIChatSceneState(); -} - -class _AIChatSceneState extends State { - // final String apiKey = "sk-3adfd188a3134e718bbf704f525aff17"; - final Doubao doubao = Doubao( - apiKey: "418ec475-e2dc-4b76-8aca-842d81bc3466", - modelId: "ep-20250203161136-9lrxg"); - - final List _chats = [ChatItem(msg: "我是测试代码")]; - ChatItem? _currchat; - final TextEditingController _textController = TextEditingController(); - - //发送消息 - _sendMessage() async { - _currchat = ChatItem(msg: ""); - setState(() { - _chats.add(_currchat!); - }); - var stream = doubao.chat(_textController.text); - _textController.text = ""; - await for (final content in stream) { - setState(() { - _currchat?.append(content); - }); - print('实时更新: $content'); - } - print('结束恢复'); - _currchat?.end(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: Text("AI测试")), - body: ListView.builder( - itemCount: _chats.length, - itemBuilder: (context, index) { - var item = _chats[index]; - return _buildAudioMessage(item); - }, - ), - bottomNavigationBar: Padding( - padding: const EdgeInsets.all(20.0), - child: Container( - decoration: BoxDecoration( - color: Colors.grey[200], // 背景颜色 - borderRadius: BorderRadius.circular(30), // 圆角 - ), - padding: EdgeInsets.symmetric( - horizontal: 20, vertical: 10), // 输入框和按钮的内边距 - child: Row( - children: [ - Expanded( - child: TextField( - controller: _textController, // 用于获取输入的文本 - decoration: InputDecoration( - hintText: '输入消息...', // 提示文本 - border: InputBorder.none, // 去除默认边框 - contentPadding: - EdgeInsets.symmetric(vertical: 12), // 调整内边距 - ), - ), - ), - IconButton( - icon: Icon(Icons.send, color: Colors.blue), // 发送按钮图标 - onPressed: _sendMessage, // 发送按钮点击事件 - ), - ], - ), - ), - )); - } - - // 构建语音消息 - Widget _buildAudioMessage(ChatItem data) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // 音频播放按钮 - GestureDetector( - onTap: () {}, - child: Container( - padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20), - decoration: BoxDecoration( - color: Colors.green, - borderRadius: BorderRadius.circular(30), - ), - child: Row( - children: [ - Text( - data.msg, - style: TextStyle(color: Colors.white), - ), - ], - ), - ), - ), - SizedBox(height: 5), - ], - ), - ); - } -} diff --git a/lib/scenes/BluetoothScene.dart b/lib/scenes/BluetoothScene.dart deleted file mode 100644 index cbf1e5e..0000000 --- a/lib/scenes/BluetoothScene.dart +++ /dev/null @@ -1,114 +0,0 @@ -// /* -// 蓝牙测试场景 -// */ -// import 'package:flutter/material.dart'; -// import 'package:flutter_blue/flutter_blue.dart'; - -// class BluetoothScene extends StatefulWidget { -// @override -// _BluetoothSceneState createState() => _BluetoothSceneState(); -// } - -// class _BluetoothSceneState extends State { -// FlutterBlue flutterBlue = FlutterBlue.instance; -// List devicesList = []; -// BluetoothDevice? connectedDevice; -// BluetoothState? bluetoothState; - -// @override -// void initState() { -// super.initState(); -// flutterBlue.state.listen((state) { -// setState(() { -// bluetoothState = state; -// }); -// }); - -// flutterBlue.scanResults.listen((results) { -// setState(() { -// devicesList = results -// .where((result) => result.device.name.isNotEmpty) -// .map((result) => result.device) -// .toList(); -// }); -// }); -// } - -// void startScan() { -// flutterBlue.startScan(timeout: Duration(seconds: 4)); -// } - -// void stopScan() { -// flutterBlue.stopScan(); -// } - -// void connectToDevice(BluetoothDevice device) async { -// await device.connect(); -// setState(() { -// connectedDevice = device; -// }); -// listenToDeviceEvents(device); -// } - -// void listenToDeviceEvents(BluetoothDevice device) { -// device.state.listen((state) { -// if (state == BluetoothDeviceState.connected) { -// print('Device connected'); -// } else if (state == BluetoothDeviceState.disconnected) { -// print('Device disconnected'); -// } -// }); - -// device.discoverServices().then((services) { -// services.forEach((service) { -// service.characteristics.forEach((characteristic) { -// characteristic.setNotifyValue(true); -// characteristic.value.listen((value) { -// print('Received value: $value'); -// }); -// }); -// }); -// }); -// } - -// @override -// Widget build(BuildContext context) { -// return Scaffold( -// appBar: AppBar(title: Text('Flutter Bluetooth Demo')), -// body: Column( -// children: [ -// if (bluetoothState == BluetoothState.off) -// Text('Bluetooth is off, please turn it on'), -// if (bluetoothState == BluetoothState.on) -// Column( -// children: [ -// ElevatedButton( -// onPressed: startScan, -// child: Text('Start Scan'), -// ), -// ElevatedButton( -// onPressed: stopScan, -// child: Text('Stop Scan'), -// ), -// ListView.builder( -// shrinkWrap: true, -// itemCount: devicesList.length, -// itemBuilder: (context, index) { -// return ListTile( -// title: Text(devicesList[index].name), -// subtitle: Text(devicesList[index].id.toString()), -// onTap: () { -// connectToDevice(devicesList[index]); -// }, -// ); -// }, -// ), -// if (connectedDevice != null) -// Text('Connected to: ${connectedDevice?.name}') -// ], -// ), -// ], -// ), -// ); -// } -// } diff --git a/lib/scenes/home/home_logic.dart b/lib/scenes/home/home_logic.dart new file mode 100644 index 0000000..499c97c --- /dev/null +++ b/lib/scenes/home/home_logic.dart @@ -0,0 +1,92 @@ +import 'dart:convert'; + +import 'package:demo001/scenes/login/login_view.dart'; +import 'package:demo001/scenes/public.dart'; +import 'package:demo001/tools/http_utils.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:get/get.dart'; +import 'package:logger/logger.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'home_state.dart'; + +/// @description: +/// @author +/// @date: 2025-01-07 15:51:34 +class HomeLogic extends GetxController { + final state = HomeState(); + + //1.已连接到的蓝牙,2.失去连接的蓝牙 + final String _bluetoothConnectStateKey = "bluetoothConnected"; + final String _bluetoothDisConnectStateKey = "bluetoothDisConnect"; + //1.已经连接的蓝牙 + final String _bluetoothAlreadyConnectKey = "bluetoothAlreadyConnected"; + + @override + void onInit() { + super.onInit(); + _getLoginInfo(); + _checkPermission(); + _checkConnectDevice(); + _checkBluetoothStatus(); + } + + void _checkPermission() { + Permission.microphone.request(); + state.methodChannel.invokeMethod("bluetoothPermissionRequest"); + } + + void _checkBluetoothStatus() {} + + ///获取登录信息 + void _getLoginInfo() async { + final info = await getSharedLoginInfo(); + if (info != null) { + state.loginModel = info; + _getAliToken(); + } else { + EasyLoading.showError('登录过期'); + Get.offAll(() => LoginScene()); + } + } + + void _getAliToken() { + ApiClient.post( + url: '/api/home/auth_alitoken', + token: state.loginModel!.data!.token!, + param: {}, + onSuccess: (data) { + // Logger().i('---------_getAliToken--------token-:${data.runtimeType}'); + // Logger().i('---------_getAliToken--------token-:${data['data']['token']}'); + state.loginModel?.ali_appkey = data['data']['appkey']; + state.loginModel?.ali_token = data['data']['token']; + }, + onFailed: (msg) { + Logger().e('-------_getAliToken-------error-$msg'); + }); + } + + ///原生传回的数据监听 + void _phoneCallRecordingListenner() { + state.eventChannel.receiveBroadcastStream((data) {}); + } + + //开始监听蓝牙连接设备状态 + void _checkConnectDevice() { + state.methodChannel.invokeMethod('checkConnectedBluetooth'); + } + + ///通话翻译按钮点击 + void startPhoneCallRecording() { + state.methodChannel.invokeMethod('startPhoneCallRecording'); + } + + ///停止通讯录音 + void stopPhoneCallRecording() { + state.methodChannel.invokeMethod('stopPhoneCallRecording'); + } + + //打开蓝牙扫描界面 + void toBonding() {} + + ///**************通话录音翻译*************** */ +} diff --git a/lib/scenes/home/home_state.dart b/lib/scenes/home/home_state.dart new file mode 100644 index 0000000..9ab405d --- /dev/null +++ b/lib/scenes/home/home_state.dart @@ -0,0 +1,23 @@ +import 'package:demo001/scenes/login/model/login_model.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; + +/// @description: +/// @author +/// @date: 2025-01-07 15:51:34 +class HomeState { + HomeState() { + ///Initialize variables + } + + EventChannel eventChannel = EventChannel('eventChannel'); + + MethodChannel methodChannel = MethodChannel('methodChannel'); + + RxString originText = 'english'.obs; + RxString translationText = '英语'.obs; + + RxString phoneNum = ''.obs; + + LoginModel? loginModel; +} diff --git a/lib/scenes/home/home_view.dart b/lib/scenes/home/home_view.dart new file mode 100644 index 0000000..a2aabcf --- /dev/null +++ b/lib/scenes/home/home_view.dart @@ -0,0 +1,235 @@ +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:audioplayers/audioplayers.dart'; +import 'package:demo001/gen/assets.gen.dart'; +import 'package:demo001/generated/l10n.dart'; +import 'package:demo001/main.dart'; +import 'package:demo001/tools/color_utils.dart'; +import 'package:demo001/tools/textStyle.dart'; +import 'package:demo001/tools/widgets.dart'; +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:get/get.dart'; +import 'package:logger/logger.dart'; +import 'package:path_provider/path_provider.dart'; + +import 'home_logic.dart'; +import 'home_state.dart'; + +/// @description: +/// @author +/// @date: 2025-01-07 15:51:34 +class HomePage extends StatelessWidget { + final HomeLogic logic = Get.put(HomeLogic()); + final HomeState state = Get.find().state; + + double width = 0; + double height = 0; + + @override + Widget build(BuildContext context) { + s = S.of(context); + width = MediaQuery.of(context).size.width; + height = MediaQuery.of(context).size.height; + return Scaffold( + backgroundColor: bgColor, + body: SafeArea( + child: Container( + padding: EdgeInsets.all(10), + alignment: Alignment.center, + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + alignment: Alignment.center, + child: Obx(() => Text( + state.phoneNum.value, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: white), + )), + ), + const Gap(12), + Center( + child: Image.asset( + 'assets/icon/home_img.png', + width: width * 0.5, + fit: BoxFit.fitWidth, + ), + ), + const Gap(20), + GestureDetector( + onTap: logic.toBonding, + child: Center( + child: Container( + height: 40, + decoration: BoxDecoration( + color: white, + borderRadius: BorderRadius.circular(20), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Gap(20), + Container( + width: 20, + height: 20, + alignment: Alignment.center, + decoration: BoxDecoration( + color: blue, + borderRadius: BorderRadius.circular(4)), + child: Icon( + Icons.bluetooth, + color: white, + size: 15, + ), + ), + Gap(5), + Obx(() => Text( + '请连接耳机', + style: TextStyle(fontSize: 14, color: black), + )), + const Gap(20), + ], + ), + ), + ), + ), + const Gap(10), + Text( + '智能工具', + style: TextStyle( + fontSize: 18, fontWeight: FontWeight.bold, color: white), + ), + const Gap(10), + GestureDetector( + onTap: () { + //Get.to(() => AiChatPage(loginModel: state.loginModel!)); + }, + child: Stack( + children: [ + Assets.icon.homeAiModel.image(fit: BoxFit.fitHeight), + Positioned( + left: 20, + top: 120 * 0.5 - + textSize('AI对话模式', Style.homeItemTextStyle).height * + 0.5, + child: Text( + 'AI对话模式', + style: Style.homeItemTextStyle, + ), + ) + ], + ), + ), + const Gap(10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + //Get.to(() => Tcty_chatPage()); + }, + child: Stack( + children: [ + Assets.icon.homeIconTcty.image( + width: (width - 30) * 0.5, fit: BoxFit.fitWidth), + Positioned( + left: (width - 30) * 0.25 - + textSize('同声传译', Style.homeItemTextStyle) + .width * + 0.5, + top: (width - 30) * 0.5 - 50, + child: Text( + '同声传译', + style: Style.homeItemTextStyle, + ), + ) + ], + ), + ), + GestureDetector( + onTap: () async {}, + child: Stack( + children: [ + Assets.icon.homeIconMdmfy.image( + width: (width - 30) * 0.5, fit: BoxFit.fitWidth), + Positioned( + left: (width - 30) * 0.25 - + textSize('面对面翻译', Style.homeItemTextStyle) + .width * + 0.5, + top: (width - 30) * 0.5 - 50, + child: Text( + '面对面翻译', + style: Style.homeItemTextStyle, + ), + ) + ], + ), + ), + ], + ), + const Gap(10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + // Get.to(() => PhonecallAudioTranslatePage()); + // state.methodChannel + // .invokeMethod('googleRealTimeSpeechToText'); + }, + child: Stack( + children: [ + Assets.icon.homeIconThyyfy.image( + width: (width - 30) * 0.5, fit: BoxFit.fitWidth), + Positioned( + left: (width - 30) * 0.25 - + textSize('通话语音翻译', Style.homeItemTextStyle) + .width * + 0.5, + top: (width - 30) * 0.5 - 50, + child: Text( + '通话语音翻译', + style: Style.homeItemTextStyle, + ), + ) + ], + ), + ), + GestureDetector( + onTap: () { + // Get.to(() => TransRecordsPage()); + }, + child: Stack( + children: [ + Assets.icon.homeIconFyjl.image( + width: (width - 30) * 0.5, fit: BoxFit.fitWidth), + Positioned( + left: (width - 30) * 0.25 - + textSize('翻译记录', Style.homeItemTextStyle) + .width * + 0.5, + top: (width - 30) * 0.5 - 50, + child: Text( + '翻译记录', + style: Style.homeItemTextStyle, + ), + ) + ], + ), + ), + ], + ) + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/scenes/login/login_logic.dart b/lib/scenes/login/login_logic.dart new file mode 100644 index 0000000..9ec85c4 --- /dev/null +++ b/lib/scenes/login/login_logic.dart @@ -0,0 +1,105 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:demo001/main.dart'; +import 'package:demo001/scenes/public.dart'; +import 'package:demo001/tools/http_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:get/get.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:demo001/tools/widgets.dart'; + +import 'login_state.dart'; + +/// @description: +/// @author +/// @date: 2025-01-11 17:25:10 +class LoginLogic extends GetxController { + final state = LoginState(); + + @override + void onInit() { + super.onInit(); + } + + @override + void onReady() { + super.onReady(); + _getLoginInfo(); + _checkPermission(); + } + + void _checkPermission() { + state.methodChannel.invokeMethod("bluetoothPermissionRequest"); + } + + void _getLoginInfo() async { + EasyLoading.show(); + final info = await getSharedLoginInfo(); + if (info != null) { + state.emailContr.text = info.data?.user?.mail ?? ''; + Future.delayed(1.seconds, () { + EasyLoading.dismiss(); + Get.offAll(() => IndexWidget()); + }); + } else { + EasyLoading.dismiss(); + } + } + + void getEmailPin() { + if (state.countDown.value != 60) return; + state.pinCodeTimer = Timer.periodic(1.seconds, (t) { + if (state.countDown.value <= 0) { + t.cancel(); + state.pinCodeTimer?.cancel(); + state.pinCodeTimer = null; + state.countDown.value = 60; + } else { + state.countDown.value = state.countDown.value - 1; + } + }); + EasyLoading.show(); + ApiClient.post( + url: ApiClient.getPin, + param: {"addr": state.emailContr.text, "vtype": 0}, + onSuccess: (data) { + EasyLoading.showInfo('验证码已发送,请到邮箱查看!'); + }, + onFailed: (msg) { + EasyLoading.showError(msg); + }); + } + + void login() { + FocusScope.of(Get.context!).unfocus(); + if (!isEmail(state.emailContr.text)) { + EasyLoading.showError('邮箱错误!'); + return; + } + if (state.pinContr.text.length != 4) { + EasyLoading.showError('验证码错误!'); + return; + } + EasyLoading.show(); + ApiClient.post( + url: ApiClient.login, + param: { + "mail": state.emailContr.text, + "openid": "", + "phone": "", + "stype": 0, + "vcode": state.pinContr.text + }, + onSuccess: (data) async { + EasyLoading.dismiss(); + final instance = await SharedPreferences.getInstance(); + await instance.setString('loginInfo', jsonEncode(data)); + Get.offAll(() => IndexWidget()); + }, + onFailed: (msg) { + EasyLoading.showError(msg); + }); + } +} diff --git a/lib/scenes/login/login_state.dart b/lib/scenes/login/login_state.dart new file mode 100644 index 0000000..8e7fede --- /dev/null +++ b/lib/scenes/login/login_state.dart @@ -0,0 +1,32 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; + +/// @description: +/// @author +/// @date: 2025-01-11 17:25:10 +class LoginState { + TextEditingController phoneContr = TextEditingController(); + TextEditingController pinContr = TextEditingController(); + TextEditingController emailContr = TextEditingController(); + + MethodChannel methodChannel = MethodChannel('methodChannel'); + + FocusNode phoneNode = FocusNode(); + FocusNode emailNode = FocusNode(); + FocusNode pinNode = FocusNode(); + + // RxString phoneNumber = ''.obs; + + RxString countryCode = '86'.obs; + + RxBool protocolCheck = false.obs; + + Timer? pinCodeTimer; + + RxInt countDown = 60.obs; + + RxBool isWechatLogin = false.obs; +} diff --git a/lib/scenes/login/login_view.dart b/lib/scenes/login/login_view.dart new file mode 100644 index 0000000..bf9e03e --- /dev/null +++ b/lib/scenes/login/login_view.dart @@ -0,0 +1,317 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; +import 'package:gap/gap.dart'; +import 'package:get/get.dart'; +import 'package:demo001/tools/color_utils.dart'; +import 'package:demo001/tools/textStyle.dart'; +import 'package:demo001/tools/widgets.dart'; + +import 'login_logic.dart'; +import 'login_state.dart'; + +/// @description: +/// @author +/// @date: 2025-01-11 17:25:10 +class LoginScene extends StatelessWidget { + final LoginLogic logic = Get.put(LoginLogic()); + final LoginState state = Get.find().state; + + LoginScene({Key? key}) : super(key: key); + + double width = 0; + double height = 0; + + @override + Widget build(BuildContext context) { + width = MediaQuery.of(context).size.width; + height = MediaQuery.of(context).size.height; + return Scaffold( + backgroundColor: Color.fromARGB(255, 18, 19, 24), + body: KeyboardDismissOnTap( + child: Container( + height: height, + padding: EdgeInsets.all(8), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Gap(45), + topWidget, + Gap(50), + logo, + Gap(15), + emailInput, + Gap(15), + pinInput, + Gap(30), + loginBtn, + Gap(80), + otherLogin, + Gap(180), + protocolWidget, + Gap(15), + ], + ), + ), + ), + ), + ); + } + + Widget get topWidget => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '联系客服', + style: Style.clean, + ), + Text( + '登录/注册账号', + style: Style.navTitle, + ), + Text( + '联系客服', + style: Style.normalWhiteGrey, + ) + ], + ); + + Widget get logo => Container( + child: Icon( + Icons.logo_dev, + size: 100, + color: white, + ), + ); + + Widget get phoneInput => SizedBox( + width: width * 0.9, + child: Container( + height: 45, + decoration: BoxDecoration( + color: inputBgColor, borderRadius: BorderRadius.circular(8)), + child: Obx(() => TextField( + controller: state.phoneContr, + focusNode: state.phoneNode, + textInputAction: TextInputAction.next, + style: Style.normalBold, + keyboardType: TextInputType.phone, + inputFormatters: state.countryCode.value == '86' + ? [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), + LengthLimitingTextInputFormatter(11), + ] + : [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), + ], + decoration: InputDecoration( + border: InputBorder.none, + hintText: '请输入手机号', + contentPadding: EdgeInsets.symmetric(horizontal: 8), + ), + onSubmitted: (value) { + if (value.length != 11) { + EasyLoading.showError('手机号码错误!'); + } else { + state.emailNode.nextFocus(); + } + }, + )), + ), + ); + + Widget get emailInput => SizedBox( + width: width * 0.9, + child: Container( + height: 45, + decoration: BoxDecoration( + color: inputBgColor, borderRadius: BorderRadius.circular(8)), + child: TextField( + controller: state.emailContr, + focusNode: state.emailNode, + style: Style.normalBold, + textInputAction: TextInputAction.next, + keyboardType: TextInputType.emailAddress, + decoration: InputDecoration( + border: InputBorder.none, + hintText: '请输入邮箱', + contentPadding: EdgeInsets.symmetric(horizontal: 8), + ), + onSubmitted: (value) { + final emailRegex = + RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'); + if (!emailRegex.hasMatch(state.emailContr.text)) { + EasyLoading.showError('邮箱输入错误,请重新输入!'); + } else { + state.pinNode.nextFocus(); + } + }, + ), + ), + ); + + Widget get pinInput => SizedBox( + width: width * 0.9, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + height: 45, + width: width * 0.5, + decoration: BoxDecoration( + color: inputBgColor, borderRadius: BorderRadius.circular(8)), + child: Obx(() => TextField( + controller: state.pinContr, + focusNode: state.pinNode, + style: Style.normalBold, + textInputAction: TextInputAction.send, + keyboardType: TextInputType.phone, + inputFormatters: state.countryCode.value == '86' + ? [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), + LengthLimitingTextInputFormatter(4), + ] + : [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), + ], + decoration: InputDecoration( + border: InputBorder.none, + hintText: '请输入验证码', + contentPadding: EdgeInsets.symmetric(horizontal: 8), + ), + onSubmitted: (value) { + if (value.length != 4) { + EasyLoading.showError("验证码错误"); + } else { + logic.login(); + } + }, + )), + ), + GestureDetector( + onTap: () { + if (!isEmail(state.emailContr.text)) { + EasyLoading.showError('邮箱输入错误,请重新输入!'); + } else { + logic.getEmailPin(); + } + }, + child: Container( + height: 45, + width: width * 0.35, + alignment: Alignment.center, + decoration: BoxDecoration( + color: lightBlue, borderRadius: BorderRadius.circular(8)), + child: Obx(() => Text( + state.countDown.value == 60 + ? '获取验证码' + : '${state.countDown.value}S后重新获取', + style: Style.normalWhiteGrey, + )), + ), + ) + ], + ), + ); + + Widget get loginBtn => GestureDetector( + onTap: logic.login, + child: Container( + height: 45, + width: width * 0.9, + alignment: Alignment.center, + decoration: BoxDecoration( + color: blue, borderRadius: BorderRadius.circular(8)), + child: Obx(() => Text( + state.isWechatLogin.value ? '确定绑定' : '登录', + style: Style.normalBold, + )), + ), + ); + + Widget get otherLogin => Container( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + color: white.withAlpha(30), + height: 1, + width: width * 0.25, + ), + Text( + ' 其他登录方式 ', + style: Style.normalSmallWhiteGrey, + ), + Container( + color: white.withAlpha(30), + height: 1, + width: width * 0.25, + ), + ], + ), + Gap(15), + GestureDetector( + onTap: () { + state.isWechatLogin.value = !state.isWechatLogin.value; + }, + child: Icon( + Icons.wechat, + size: 60, + color: green, + ), + ), + ], + ), + ); + + Widget get protocolWidget => Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + onTap: () { + state.protocolCheck.value = !state.protocolCheck.value; + }, + child: Row( + children: [ + Obx(() => Container( + child: Icon( + state.protocolCheck.value + ? Icons.check_circle + : Icons.radio_button_unchecked, + color: state.protocolCheck.value ? blue : white, + size: 16, + ), + )), + Text( + ' 我已阅读并同意', + style: Style.normalSmall2, + ), + ], + ), + ), + GestureDetector( + onTap: () {}, + child: Text( + '《用户服务协议》', + style: Style.normalBlueSmall2, + ), + ), + Text( + '和', + style: Style.normalSmall2, + ), + GestureDetector( + onTap: () {}, + child: Text( + '《用户服务协议》', + style: Style.normalBlueSmall2, + ), + ) + ], + ); +} diff --git a/lib/scenes/login/model/data.dart b/lib/scenes/login/model/data.dart new file mode 100644 index 0000000..72d6b9d --- /dev/null +++ b/lib/scenes/login/model/data.dart @@ -0,0 +1,20 @@ +import 'package:json_annotation/json_annotation.dart'; + +import 'user.dart'; + +part 'data.g.dart'; + +@JsonSerializable() +class Data { + String? token; + User? user; + + Data({this.token, this.user}); + + @override + String toString() => 'Data(token: $token, user: $user)'; + + factory Data.fromJson(Map json) => _$DataFromJson(json); + + Map toJson() => _$DataToJson(this); +} diff --git a/lib/scenes/login/model/data.g.dart b/lib/scenes/login/model/data.g.dart new file mode 100644 index 0000000..6bfbf0c --- /dev/null +++ b/lib/scenes/login/model/data.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'data.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Data _$DataFromJson(Map json) => Data( + token: json['token'] as String?, + user: json['user'] == null + ? null + : User.fromJson(json['user'] as Map), + ); + +Map _$DataToJson(Data instance) => { + 'token': instance.token, + 'user': instance.user, + }; diff --git a/lib/scenes/login/model/login_model.dart b/lib/scenes/login/model/login_model.dart new file mode 100644 index 0000000..78503b0 --- /dev/null +++ b/lib/scenes/login/model/login_model.dart @@ -0,0 +1,26 @@ +import 'package:json_annotation/json_annotation.dart'; + +import 'data.dart'; + +part 'login_model.g.dart'; + +@JsonSerializable() +class LoginModel { + int? code; + Data? data; + String? msg; + + String? ali_token; + String? ali_appkey; + + LoginModel({this.code, this.data, this.msg}); + + @override + String toString() => 'LoginModel(code: $code, data: $data, msg: $msg)'; + + factory LoginModel.fromJson(Map json) { + return _$LoginModelFromJson(json); + } + + Map toJson() => _$LoginModelToJson(this); +} diff --git a/lib/scenes/login/model/login_model.g.dart b/lib/scenes/login/model/login_model.g.dart new file mode 100644 index 0000000..303a24c --- /dev/null +++ b/lib/scenes/login/model/login_model.g.dart @@ -0,0 +1,22 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LoginModel _$LoginModelFromJson(Map json) => LoginModel( + code: (json['code'] as num?)?.toInt(), + data: json['data'] == null + ? null + : Data.fromJson(json['data'] as Map), + msg: json['msg'] as String?, + ); + +Map _$LoginModelToJson(LoginModel instance) => + { + 'code': instance.code, + 'data': instance.data, + 'msg': instance.msg, + }; diff --git a/lib/scenes/login/model/user.dart b/lib/scenes/login/model/user.dart new file mode 100644 index 0000000..8018e13 --- /dev/null +++ b/lib/scenes/login/model/user.dart @@ -0,0 +1,37 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'user.g.dart'; + +@JsonSerializable() +class User { + String? avatar; + int? createtime; + String? language; + int? lastbettime; + String? mail; + String? name; + String? phone; + String? uid; + String? wxopenid; + + User({ + this.avatar, + this.createtime, + this.language, + this.lastbettime, + this.mail, + this.name, + this.phone, + this.uid, + this.wxopenid, + }); + + @override + String toString() { + return 'User(avatar: $avatar, createtime: $createtime, language: $language, lastbettime: $lastbettime, mail: $mail, name: $name, phone: $phone, uid: $uid, wxopenid: $wxopenid)'; + } + + factory User.fromJson(Map json) => _$UserFromJson(json); + + Map toJson() => _$UserToJson(this); +} diff --git a/lib/scenes/login/model/user.g.dart b/lib/scenes/login/model/user.g.dart new file mode 100644 index 0000000..ef58abb --- /dev/null +++ b/lib/scenes/login/model/user.g.dart @@ -0,0 +1,31 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +User _$UserFromJson(Map json) => User( + avatar: json['avatar'] as String?, + createtime: (json['createtime'] as num?)?.toInt(), + language: json['language'] as String?, + lastbettime: (json['lastbettime'] as num?)?.toInt(), + mail: json['mail'] as String?, + name: json['name'] as String?, + phone: json['phone'] as String?, + uid: json['uid'] as String?, + wxopenid: json['wxopenid'] as String?, + ); + +Map _$UserToJson(User instance) => { + 'avatar': instance.avatar, + 'createtime': instance.createtime, + 'language': instance.language, + 'lastbettime': instance.lastbettime, + 'mail': instance.mail, + 'name': instance.name, + 'phone': instance.phone, + 'uid': instance.uid, + 'wxopenid': instance.wxopenid, + }; diff --git a/lib/scenes/public.dart b/lib/scenes/public.dart new file mode 100644 index 0000000..5816a1d --- /dev/null +++ b/lib/scenes/public.dart @@ -0,0 +1,14 @@ +import 'dart:convert'; + +import 'package:demo001/scenes/login/model/login_model.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +Future getSharedLoginInfo() async { + final instance = await SharedPreferences.getInstance(); + final loginInfoStr = instance.getString('loginInfo'); + if (loginInfoStr != null && loginInfoStr != '') { + return LoginModel.fromJson(jsonDecode(loginInfoStr)); + } else { + return null; + } +} diff --git a/lib/scenes/translate/TranslateLogic.dart b/lib/scenes/translate/TranslateLogic.dart index d708eb4..eafcf73 100644 --- a/lib/scenes/translate/TranslateLogic.dart +++ b/lib/scenes/translate/TranslateLogic.dart @@ -4,6 +4,7 @@ import 'dart:typed_data'; import 'package:demo001/scenes/translate/TranslateState.dart'; import 'package:demo001/tools/audio_tool.dart'; +import 'package:demo001/xunfei/phonetic_dictation/phonetic_dictaion_model/w.dart'; import 'package:demo001/xunfei/recognition_result/recognition_content/recognition_content.dart'; import 'package:demo001/xunfei/xunfei_translate.dart'; import 'package:get/get.dart'; @@ -103,22 +104,66 @@ class TranslateLogic extends GetxController { void _handleRecognaitionData(result) { KDXFSentenceModel model; + String text = ""; try { final index = state.kdxfSentenceList.indexWhere((KDXFSentenceModel e) { return e.sid == result.header?.sid; }); if (index != -1) { model = state.kdxfSentenceList[index]; + final recogContextStr = utf8.decode( + base64Decode(result.payload?.recognitionResults?.text ?? '')); + final ctx = RecognitionContent.fromJson(jsonDecode(recogContextStr)); + if (ctx.pgs == 'apd') { + String text = state.kdxfSentenceList[index].content; + state.kdxfSentenceList[index].contentList.add(ctx); + ctx.ws!.forEach((e) { + e.cw?.forEach((e2) { + text = text + (e2.w ?? ''); + }); + }); + if (text.trim() == '') return; + state.kdxfSentenceList[index].content = text; + state.kdxfSentenceList.refresh(); + } else if (ctx.pgs == 'rpl') { + String text = ''; + for (var i = ctx.rg?[0]; i! <= ctx.rg![1]; i++) { + state.kdxfSentenceList[index].contentList.removeWhere((ee) { + return ee.sn == i; + }); + } + state.kdxfSentenceList[index].contentList.add(ctx); + state.kdxfSentenceList[index].contentList.forEach((e) { + e.ws?.forEach((ee) { + ee.cw?.forEach((e2) { + text = text + (e2.w ?? ''); + }); + }); + }); + if (text.trim() == '') return; + state.kdxfSentenceList[index].content = text; + state.kdxfSentenceList.refresh(); + // } + } } else { final recogContextStr = utf8.decode( base64Decode(result.payload?.recognitionResults?.text ?? '')); - final model = RecognitionContent.fromJson(jsonDecode(recogContextStr)); + final ctx = RecognitionContent.fromJson(jsonDecode(recogContextStr)); + ctx.ws!.forEach((e) { + e.cw?.forEach((e2) { + text = text + (e2.w ?? ''); + }); + }); + if (text == '') return; model = KDXFSentenceModel( - content: "", - sid: result.header?.sid ?? '', - transResult: '', - audioPath: '', - perviousWs: model.ws ?? []); + content: text, + sid: result.header?.sid ?? '', + transResult: '', + audioPath: '', + perviousWs: (ctx.ws ?? []) as List, + ); + state.kdxfSentenceList.add(model); + state.kdxfSentenceList.refresh(); } } catch (e) { print("接收识别结果异常 $e"); @@ -129,6 +174,10 @@ class TranslateLogic extends GetxController { void _handleAudioData(AudioModel model) {} + void kdxfPlayAudio(KDXFSentenceModel model) async { + model.playerController.startPlayer(); + } + void _log(String msg) { Logger().f("LIWEI---------------:$msg"); } diff --git a/lib/scenes/translate/TranslateScene.dart b/lib/scenes/translate/TranslateScene.dart index 9e938c1..8b05e61 100644 --- a/lib/scenes/translate/TranslateScene.dart +++ b/lib/scenes/translate/TranslateScene.dart @@ -1,3 +1,8 @@ +import 'package:audio_waveforms/audio_waveforms.dart'; +import 'package:demo001/gen/assets.gen.dart'; +import 'package:demo001/tools/color_utils.dart'; +import 'package:demo001/tools/textStyle.dart'; +import 'package:gap/gap.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'TranslateLogic.dart'; @@ -6,21 +11,30 @@ import 'TranslateState.dart'; /* 录音测试场景 */ +// ignore: must_be_immutable class TranslateScene extends StatelessWidget { final TranslateLogic logic = Get.put(TranslateLogic()); final TranslateState state = Get.find().state; TranslateScene({super.key}); + double width = 0; + double height = 0; @override Widget build(BuildContext context) { + width = MediaQuery.of(context).size.width; + height = MediaQuery.of(context).size.height; return Scaffold( - appBar: AppBar(title: Text("录音测试")), - // body: ListView.builder( - // itemCount: _records.length, - // itemBuilder: (context, index) { - // var audio = _records[index]; - // return _buildAudioMessage(audio); - // }, - // ), + appBar: AppBar( + title: Text( + "同声传译", + style: Style.navTitle, + )), + body: ListView.builder( + itemCount: state.kdxfSentenceList.length, + itemBuilder: (context, index) { + var audio = state.kdxfSentenceList[index]; + return _buildAudioMessage(audio); + }, + ), bottomNavigationBar: Padding( padding: const EdgeInsets.all(20.0), child: InkWell( @@ -59,47 +73,80 @@ class TranslateScene extends StatelessWidget { } // 构建语音消息 - // Widget _buildAudioMessage(RecordData data) { - // Color buttColor = data.state == 0 ? Colors.red : Colors.green; - // return Padding( - // padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15), - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // // 音频播放按钮 - // GestureDetector( - // onTap: () { - // // _playRecording(data); - // }, - // child: Container( - // padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20), - // decoration: BoxDecoration( - // color: buttColor, - // borderRadius: BorderRadius.circular(30), - // ), - // child: Row( - // children: [ - // Icon( - // Icons.play_arrow, - // color: Colors.white, - // ), - // SizedBox(width: 10), - // Text( - // '播放音频', - // style: TextStyle(color: Colors.white), - // ), - // ], - // ), - // ), - // ), - // SizedBox(height: 5), - // // 文字内容 - // // Text( - // // message['text'], - // // style: TextStyle(fontSize: 16), - // // ), - // ], - // ), - // ); - // } + Widget _buildAudioMessage(KDXFSentenceModel model) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15), + child: Row( + children: [ + const Gap(10), + Assets.img.imageAi.image(width: 25, height: 25), + const Gap(10), + Flexible( + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: width * 0.7), + child: Container( + padding: EdgeInsets.all(10), + margin: EdgeInsets.only(top: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: bottomNavBg, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + textAlign: TextAlign.start, + model.content, + style: Style.normal, + maxLines: 1000, + ), + Obx(() => Visibility( + visible: model.transResult != '', child: Gap(5))), + Obx(() => Visibility( + visible: model.transResult != '', + child: Text( + textAlign: TextAlign.start, + model.transResult, + style: Style.normal, + maxLines: 1000, + ), + )), + Obx(() => Visibility( + visible: model.audioDuration > 0, + child: const Gap(10), + )), + Obx( + () => Visibility( + visible: model.audioDuration > 0, + child: GestureDetector( + onTap: () { + logic.kdxfPlayAudio(model); + }, + child: ClipRRect( + borderRadius: BorderRadius.circular(5), + child: AudioFileWaveforms( + size: Size(165, 30), + decoration: BoxDecoration( + border: Border.all(color: orange, width: 0.5), + borderRadius: BorderRadius.circular(5), + ), + enableSeekGesture: false, + waveformType: WaveformType.fitWidth, + playerWaveStyle: PlayerWaveStyle( + waveThickness: 2, scaleFactor: 50), + playerController: model.playerController, + ), + ), + ), + ), + ) + ], + ), + ), + ), + ), + ], + ), + ); + } } diff --git a/lib/tools/color_utils.dart b/lib/tools/color_utils.dart new file mode 100644 index 0000000..5beaba1 --- /dev/null +++ b/lib/tools/color_utils.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'dart:math'; + +MaterialColor createMaterialColor(Color color) { + List strengths = [.05]; + Map swatch = {}; + final int r = color.red, g = color.green, b = color.blue; + + for (int i = 1; i < 10; i++) { + strengths.add(0.1 * i); + } + for (var strength in strengths) { + final double ds = 0.5 - strength; + swatch[(strength * 1000).round()] = Color.fromRGBO( + r + ((ds < 0 ? r : (255 - r)) * ds).round(), + g + ((ds < 0 ? g : (255 - g)) * ds).round(), + b + ((ds < 0 ? b : (255 - b)) * ds).round(), + 1, + ); + } + return MaterialColor(color.value, swatch); +} + +Color randomColor() { + return Color.fromARGB( + 255, Random().nextInt(256), Random().nextInt(256), Random().nextInt(256)); +} + +const Color bottomNavBg = Color.fromARGB(255, 31, 33, 39); +const Color silver = Color.fromARGB(255, 194, 195, 197); +const Color white = Colors.white; +const Color whiteGrey = Color.fromARGB(255, 224, 224, 224); +const Color inputBgColor = Color.fromARGB(255, 44, 46, 53); + +const Color chatBlue = Color.fromARGB(255, 80, 158, 171); + +// const Color white = Colors.black; +const Color bgColor = Color.fromARGB(255, 18, 19, 24); +// const Color bgColor = Colors.grey; +const Color blue = Color.fromARGB(255, 72, 90, 255); +const Color lightBlue = Color.fromARGB(255, 55, 56, 110); +const Color deepBlue = Color.fromARGB(255, 18, 19, 41); +const Color black = Color.fromARGB(255, 31, 32, 35); +const Color red = Color.fromARGB(255, 225, 118, 129); +const Color lightRed = Color.fromARGB(255, 224, 143, 152); +const Color orange = Color.fromARGB(255, 235, 176, 41); +const Color lightOrange = Color.fromARGB(255, 234, 200, 120); +const Color clean = Colors.transparent; +const Color grey = Color.fromARGB(255, 129, 129, 130); +const Color lightGrey = Color.fromARGB(255, 228, 228, 228); +const Color green = Color.fromARGB(255, 41, 196, 72); +const Color lightGreen = Color.fromARGB(255, 137, 214, 153); diff --git a/lib/tools/http_utils.dart b/lib/tools/http_utils.dart new file mode 100644 index 0000000..63279de --- /dev/null +++ b/lib/tools/http_utils.dart @@ -0,0 +1,259 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:logger/logger.dart'; +import 'package:http/http.dart' as http; + +class ApiClient { + static final _client = Dio(); + + static String _baseUrl = 'https://www.aitoyyun.com'; + + static get( + {String baseUrl = 'https://www.aitoyyun.com', + required String url, + required Map param, + required Function(Map) onSuccess, + required Function(String) onFailed}) async { + _baseUrl = baseUrl; + try { + Response response = await _client.get( + _baseUrl + url.trim(), + options: Options( + headers: {"Accept": 'application/json'}, + sendTimeout: const Duration(seconds: 10), + receiveTimeout: const Duration(seconds: 10)), + queryParameters: param, + ); + final jsonData = response.data; + _progressData( + jsonData: jsonData, onSuccess: onSuccess, onFailed: onFailed); + } on DioException catch (e) { + _progressError(response: e.response, onFailed: onFailed); + } + } + + static post( + {required String url, + String? token, + required Map param, + required Function(Map) onSuccess, + required Function(String) onFailed}) async { + try { + // Logger().i('---url: ${_baseUrl + url.trim()}---param: $param-----token: $token'); + Response response = await _client.post( + _baseUrl + url.trim(), + options: Options( + headers: {'Authorization': token ?? ''}, + sendTimeout: const Duration(seconds: 10), + receiveTimeout: const Duration(seconds: 10)), + queryParameters: param, + data: param, + ); + final jsonData = response.data; + _progressData( + jsonData: jsonData, onSuccess: onSuccess, onFailed: onFailed); + } on DioException catch (e) { + _progressError(response: e.response, onFailed: onFailed); + } + } + + static put( + {required String url, + required Map param, + required Function(Map) onSuccess, + required Function(String) onFailed}) async { + try { + Response response = await _client.put( + _baseUrl + url.trim(), + options: Options( + headers: {"Accept": 'application/json'}, + sendTimeout: const Duration(seconds: 10), + receiveTimeout: const Duration(seconds: 10)), + queryParameters: param, + data: param, + ); + final jsonData = response.data; + _progressData( + jsonData: jsonData, onSuccess: onSuccess, onFailed: onFailed); + } on DioException catch (e) { + _progressError(response: e.response, onFailed: onFailed); + } + } + + static delete( + {required String url, + required Map param, + required Function(Map) onSuccess, + required Function(String) onFailed}) async { + try { + Response response = await _client.delete( + _baseUrl + url.trim(), + options: Options( + headers: {"Accept": 'application/json'}, + sendTimeout: const Duration(seconds: 10), + receiveTimeout: const Duration(seconds: 10)), + queryParameters: param, + data: param, + ); + final jsonData = response.data; + _progressData( + jsonData: jsonData, onSuccess: onSuccess, onFailed: onFailed); + } on DioException catch (e) { + _progressError(response: e.response, onFailed: onFailed); + } + } + + static void _progressData( + {required Map jsonData, + required Function(Map) onSuccess, + required Function(String) onFailed}) { + // Logger().i('--_progressData------${jsonData}'); + if (jsonData['code'] == 0) { + onSuccess(jsonData); + } else { + onFailed(jsonData['msg'].toString()); + } + } + + static void _progressError( + {Response? response, required Function(String) onFailed}) { + if (response != null && response.data != null) { + Logger().i('_progressError---------${response.data}'); + if (response.data.runtimeType == String) { + onFailed('返回数据格式错误'); + } else { + if (response.data['errCode'] != null) { + final jsonData = response.data; + onFailed(jsonData['errMsg'].toString()); + } else { + final jsonData = response.data; + onFailed(jsonData['state']['msg'].toString()); + } + } + } else { + onFailed('请求失败'); + } + } + + static final String login = '/api/home/user_sgin'; + + static final String getPin = '/api/home/user_verification'; + + // static final String aiChat = '/api/home/ai_chat'; + + static final String deepseekApiKey = 'sk-3adfd188a3134e718bbf704f525aff17'; + static Stream aiChat(String prompt) async* { + final client = HttpClient(); + try { + final request = await client + .postUrl(Uri.parse('https://api.deepseek.com/chat/completions')); + + // 设置流式请求头 + request.headers + ..set('Content-Type', 'application/json') + ..set('Authorization', 'Bearer $deepseekApiKey') + ..set('Accept', 'text/event-stream'); + + // 构建请求体 + final requestBody = jsonEncode({ + 'model': 'deepseek-chat', + 'stream': true, + 'messages': [ + {'role': 'user', 'content': prompt} + ] + }); + + // 写入请求体 + request.add(utf8.encode(requestBody)); + final response = await request.close(); + + // 检查状态码 + if (response.statusCode != 200) { + throw Exception('API请求失败: ${response.statusCode}'); + } + + // 处理流数据 + String buffer = ''; + await for (final chunk in response.transform(utf8.decoder)) { + buffer += chunk; + + // 分割完整事件(假设使用SSE格式) + while (buffer.contains('\n\n')) { + final eventEnd = buffer.indexOf('\n\n'); + final event = buffer.substring(0, eventEnd); + buffer = buffer.substring(eventEnd + 2); + + if (event.startsWith('data: ')) { + final dataContent = event.substring(6); + // 增加有效性检查 + if (dataContent == '[DONE]') { + // print('流式传输结束'); + continue; // 跳过特殊结束标记 + } + final jsonData = jsonDecode(event.substring(6)); + yield jsonData['choices'][0]['delta']['content']; + } + } + } + } finally { + client.close(); + } + } + + static final String dbAppkey = '418ec475-e2dc-4b76-8aca-842d81bc3466'; + static final String dbModelId = 'ep-20250203161136-9lrxg'; + static Stream dbChat(String userMessage) async* { + final client = http.Client(); + final url = + Uri.parse('https://ark.cn-beijing.volces.com/api/v3/chat/completions'); + + final headers = { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $dbAppkey', + }; + + final requestBody = { + "model": dbModelId, + "messages": [ + {"role": "system", "content": "你是豆包,是由字节跳动开发的 AI 人工智能助手."}, + {"role": "user", "content": userMessage} + ], + "stream": true, + }; + + try { + final request = http.Request('POST', url) + ..headers.addAll(headers) + ..body = jsonEncode(requestBody); + + final response = await client.send(request); + //流式处理响应数据 + await for (final chunk in response.stream + .transform(utf8.decoder) + .transform(const LineSplitter())) { + if (chunk.isEmpty) continue; + + // 假设豆包API使用类似OpenAI的流式格式(data: {...}) + if (chunk.startsWith('data:')) { + final jsonStr = chunk.substring(5).trim(); + if (jsonStr == '[DONE]') break; // 流结束标志 + + try { + final data = jsonDecode(jsonStr); + final content = data['choices'][0]['delta']['content'] ?? ''; + if (content.isNotEmpty) { + yield content; // 逐块返回生成的文本 + } + } catch (e) { + // print('JSON解析错误: $e'); + } + // print('请求成功: $jsonStr'); + } + } + } catch (e) { + print('请求异常: $e'); + } + } +} diff --git a/lib/tools/textStyle.dart b/lib/tools/textStyle.dart new file mode 100644 index 0000000..94a8c6c --- /dev/null +++ b/lib/tools/textStyle.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:demo001/tools/color_utils.dart'; + +class Style { + static final greenBold = + TextStyle(color: green, fontSize: 18, fontWeight: FontWeight.bold); + static final navTitle = + TextStyle(color: white, fontSize: 18, fontWeight: FontWeight.bold); + static final normalWhiteGrey = + TextStyle(color: whiteGrey, fontSize: 14, fontWeight: FontWeight.bold); + static final normalBold = + TextStyle(color: white, fontSize: 16, fontWeight: FontWeight.bold); + static final normal = TextStyle(color: white, fontSize: 16); + static final normalGrey = + TextStyle(color: const Color.fromARGB(255, 92, 92, 92), fontSize: 16); + static final normalSmall = TextStyle(color: white, fontSize: 14); + static final normalGreySmall = + TextStyle(color: const Color.fromARGB(255, 92, 92, 92), fontSize: 14); + static final normalSmall2 = TextStyle(color: white, fontSize: 12); + static final normalGreySmall2 = + TextStyle(color: const Color.fromARGB(255, 92, 92, 92), fontSize: 12); + static final normalBlueSmall2 = TextStyle(color: blue, fontSize: 12); + static final normalSmallWhiteGrey = TextStyle(color: whiteGrey, fontSize: 14); + static final normalSmallBoldWhiteGrey = + TextStyle(color: whiteGrey, fontSize: 14, fontWeight: FontWeight.bold); + static final clean = TextStyle( + color: Colors.transparent, fontSize: 14, fontWeight: FontWeight.bold); + + static final homeItemTextStyle = + TextStyle(fontSize: 14, color: white, fontWeight: FontWeight.bold); + static final hintStyle = TextStyle(fontSize: 14, color: grey); +} diff --git a/lib/tools/widgets.dart b/lib/tools/widgets.dart new file mode 100644 index 0000000..871a35a --- /dev/null +++ b/lib/tools/widgets.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +Widget circleCheckBox() { + return Container( + child: Icon(Icons.check), + ); +} + +Size textSize(String text, TextStyle style) { + final TextPainter textPainter = TextPainter( + text: TextSpan(text: text, style: style), + textDirection: TextDirection.ltr, + )..layout(); // 布局文本 + return textPainter.size; // 返回文本的尺寸 +} + +bool isEmail(String email) { + final emailRegex = + RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'); + return emailRegex.hasMatch(email); +} diff --git a/lib/xunfei/xunfei_translate.dart b/lib/xunfei/xunfei_translate.dart index ed7d422..82a75c6 100644 --- a/lib/xunfei/xunfei_translate.dart +++ b/lib/xunfei/xunfei_translate.dart @@ -296,8 +296,8 @@ class XunFeiTranslateTask { onDone: () { isconnected = false; print('WebSocket 连接已关闭'); - print('Close code: ${_channel?.closeCode}'); - print('Close reason: ${_channel?.closeReason}'); + print('Close code: ${_channel.closeCode}'); + print('Close reason: ${_channel.closeReason}'); }, cancelOnError: true, ); diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 743f741..6d80946 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,10 +9,12 @@ import audio_session import audioplayers_darwin import path_provider_foundation import record_darwin +import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) RecordPlugin.register(with: registry.registrar(forPlugin: "RecordPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 472a0bf..cc3f09e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,28 +1,65 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "72.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "6.7.0" + archive: + dependency: transitive + description: + name: archive + sha256: "6199c74e3db4fbfbd04f66d739e72fe11c8a8957d5f219f1f4482dbde6420b5a" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "4.0.2" + args: + dependency: transitive + description: + name: args + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.6.0" async: dependency: transitive description: name: async sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.11.0" audio_session: dependency: transitive description: name: audio_session - sha256: a92eed06a93721bcc8a8b57d0a623e3fb9d2e4e11cef0a08ed448c73886700b7 - url: "https://pub.dev" + sha256: "2b7fff16a552486d078bfc09a8cde19f426dc6d6329262b684182597bec5b1ac" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "0.1.24" + version: "0.1.25" audio_waveforms: dependency: "direct main" description: name: audio_waveforms sha256: "26531204e539708a51a33096a9d509a68f9a748dd1fe1582c5da25add8daa041" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.0" audioplayers: @@ -30,7 +67,7 @@ packages: description: name: audioplayers sha256: "4ca57fd24594af04e93b9b9f1b1739ffb9204dbab7ce8d9b28a02f464456dcca" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.1.1" audioplayers_android: @@ -38,7 +75,7 @@ packages: description: name: audioplayers_android sha256: "6c9443ce0a99b29a840f14bc2d0f7b25eb0fd946dc592a1b8a697807d5b195f3" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.0.1" audioplayers_darwin: @@ -46,7 +83,7 @@ packages: description: name: audioplayers_darwin sha256: e507887f3ff18d8e5a10a668d7bedc28206b12e10b98347797257c6ae1019c3b - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.0.0" audioplayers_linux: @@ -54,7 +91,7 @@ packages: description: name: audioplayers_linux sha256: "9d3cb4e9533a12a462821e3f18bd282e0fa52f67ff96a06301d48dd48b82c2d1" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.0.1" audioplayers_platform_interface: @@ -62,7 +99,7 @@ packages: description: name: audioplayers_platform_interface sha256: "6834dd48dfb7bc6c2404998ebdd161f79cd3774a7e6779e1348d54a3bfdcfaa5" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "7.0.0" audioplayers_web: @@ -70,7 +107,7 @@ packages: description: name: audioplayers_web sha256: "3609bdf0e05e66a3d9750ee40b1e37f2a622c4edb796cc600b53a90a30a2ace4" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.0.1" audioplayers_windows: @@ -78,7 +115,7 @@ packages: description: name: audioplayers_windows sha256: "8605762dddba992138d476f6a0c3afd9df30ac5b96039929063eceed416795c2" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.0.0" boolean_selector: @@ -86,39 +123,135 @@ packages: description: name: boolean_selector sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "4.0.2" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.4.2" + build_runner: + dependency: "direct main" + description: + name: build_runner + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.4.13" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "7.3.2" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "28a712df2576b63c6c005c465989a348604960c0958d28be5303ba9baa841ac2" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "8.9.3" characters: dependency: transitive description: name: characters sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.0.3" clock: dependency: transitive description: name: clock sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "4.10.1" collection: dependency: transitive description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf - url: "https://pub.dev" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.18.0" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "3.0.0" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "1.19.0" + version: "3.1.2" crypto: dependency: transitive description: name: crypto sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.6" cupertino_icons: @@ -126,23 +259,55 @@ packages: description: name: cupertino_icons sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.8" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.3.7" + dartx: + dependency: transitive + description: + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.2.0" + dio: + dependency: "direct main" + description: + name: dio + sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "5.8.0+1" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: e485c7a39ff2b384fa1d7e09b4e25f755804de8384358049124830b04fc4f93a + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.1.0" etau: dependency: transitive description: name: etau - sha256: "4b43a615ecceb1de7c5a35f0a159920b4fdb8ce5a33d71d3828a31efedc67572" - url: "https://pub.dev" + sha256: "5859ee8438770e2887426dccf05bb55f2c78f20fe6db84043675155c2ebb9a7e" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "0.0.14-alpha.4" + version: "0.0.14-alpha.5" fake_async: dependency: transitive description: name: fake_async sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.3.1" ffi: @@ -150,7 +315,7 @@ packages: description: name: ffi sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.3" file: @@ -158,7 +323,7 @@ packages: description: name: file sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "7.0.1" fixnum: @@ -166,7 +331,7 @@ packages: description: name: fixnum sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.1" flutter: @@ -174,38 +339,123 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_easyloading: + dependency: "direct main" + description: + name: flutter_easyloading + sha256: ba21a3c883544e582f9cc455a4a0907556714e1e9cf0eababfcb600da191d17c + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "3.0.5" + flutter_gen_core: + dependency: transitive + description: + name: flutter_gen_core + sha256: "53890b653738f34363d9f0d40f82104c261716bd551d3ba65f648770b6764c21" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "5.9.0" + flutter_gen_runner: + dependency: "direct main" + description: + name: flutter_gen_runner + sha256: de70b42eb5329f712c8b041069d081ad5fb5109f32d6d1ea9c1b39596786215d + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "5.9.0" + flutter_keyboard_visibility: + dependency: "direct main" + description: + name: flutter_keyboard_visibility + sha256: "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "6.0.0" + flutter_keyboard_visibility_linux: + dependency: transitive + description: + name: flutter_keyboard_visibility_linux + sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.0.0" + flutter_keyboard_visibility_macos: + dependency: transitive + description: + name: flutter_keyboard_visibility_macos + sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.0.0" + flutter_keyboard_visibility_platform_interface: + dependency: transitive + description: + name: flutter_keyboard_visibility_platform_interface + sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.0.0" + flutter_keyboard_visibility_web: + dependency: transitive + description: + name: flutter_keyboard_visibility_web + sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.0.0" + flutter_keyboard_visibility_windows: + dependency: transitive + description: + name: flutter_keyboard_visibility_windows + sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.0.0" flutter_lints: dependency: "direct dev" description: name: flutter_lints sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.0.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_sound: dependency: "direct main" description: name: flutter_sound - sha256: "223949653433bfc22749e9a9725c802733ed24e6dd51c53775716c340631dcae" - url: "https://pub.dev" + sha256: "016ae9c2be7aa32b1d35c2064cb1dd5aaeecff8fd4f21b1202335a5a0e0a2f4c" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "9.20.5" + version: "9.22.0" flutter_sound_platform_interface: dependency: transitive description: name: flutter_sound_platform_interface - sha256: b85ac6eb1a482329c560e189fca75d596091c291a7d1756e0a3c9536ae87af1b - url: "https://pub.dev" + sha256: f98b6c6218ff7041bb16ea88e0e0563556401c0b65c23c5852ea3be87ddf9cfd + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "9.20.5" + version: "9.22.0" flutter_sound_web: dependency: transitive description: name: flutter_sound_web - sha256: dccae5647cdcac368723ff90a3fb2ec0d77b2e871ceb47b3de628806b0ca325c - url: "https://pub.dev" + sha256: c6327679e860009c405b768100dd878946ae67d045760a3e67e239b4fd74c3ec + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "9.20.5" + version: "9.22.0" + flutter_spinkit: + dependency: transitive + description: + name: flutter_spinkit + sha256: d2696eed13732831414595b98863260e33e8882fc069ee80ec35d4ac9ddb0472 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "5.2.1" flutter_test: dependency: "direct dev" description: flutter @@ -216,44 +466,116 @@ packages: description: flutter source: sdk version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "4.0.0" + gap: + dependency: "direct main" + description: + name: gap + sha256: f19387d4e32f849394758b91377f9153a1b41d79513ef7668c088c77dbc6955d + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "3.0.1" get: dependency: "direct main" description: name: get sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.6.6" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.1.3" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.3.2" + hashcodes: + dependency: transitive + description: + name: hashcodes + sha256: "80f9410a5b3c8e110c4b7604546034749259f5d6dcca63e0d3c17c9258f1a651" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.0.0" http: dependency: "direct main" description: name: http sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.3.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "3.2.2" http_parser: dependency: transitive description: name: http_parser - sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://pub.dev" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "4.0.2" + image_size_getter: + dependency: transitive + description: + name: image_size_getter + sha256: "9a299e3af2ebbcfd1baf21456c3c884037ff524316c97d8e56035ea8fdf35653" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "4.1.2" + version: "2.4.0" intl: dependency: "direct main" description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" - url: "https://pub.dev" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "0.19.0" + intl_utils: + dependency: "direct dev" + description: + name: intl_utils + sha256: "35f9a55004871f241e24b07465cf402914992d8549a60205ee0816576a8ddee7" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "0.20.2" + version: "2.8.8" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.0.5" js: dependency: transitive description: name: js sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.7.1" json_annotation: @@ -261,55 +583,71 @@ packages: description: name: json_annotation sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.9.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" - url: "https://pub.dev" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "10.0.7" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" - url: "https://pub.dev" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "3.0.8" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.1" lints: dependency: transitive description: name: lints - sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 - url: "https://pub.dev" + sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "5.1.1" + version: "5.0.0" logger: dependency: "direct main" description: name: logger sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.5.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.3.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "0.1.2-main.4" matcher: dependency: transitive description: name: matcher sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.12.16+1" material_color_utilities: @@ -317,7 +655,7 @@ packages: description: name: material_color_utilities sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.11.1" meta: @@ -325,31 +663,55 @@ packages: description: name: meta sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.15.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.0.0" nested: dependency: transitive description: name: nested sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.1.1" path: dependency: transitive description: name: path sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.9.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.1.0" path_provider: dependency: "direct main" description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.5" path_provider_android: @@ -357,7 +719,7 @@ packages: description: name: path_provider_android sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.2.15" path_provider_foundation: @@ -365,7 +727,7 @@ packages: description: name: path_provider_foundation sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" path_provider_linux: @@ -373,7 +735,7 @@ packages: description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.2.1" path_provider_platform_interface: @@ -381,7 +743,7 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.2" path_provider_windows: @@ -389,7 +751,7 @@ packages: description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.3.0" permission_handler: @@ -397,7 +759,7 @@ packages: description: name: permission_handler sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "11.3.1" permission_handler_android: @@ -405,7 +767,7 @@ packages: description: name: permission_handler_android sha256: "71bbecfee799e65aff7c744761a57e817e73b738fedf62ab7afd5593da21f9f1" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "12.0.13" permission_handler_apple: @@ -413,7 +775,7 @@ packages: description: name: permission_handler_apple sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "9.4.5" permission_handler_html: @@ -421,7 +783,7 @@ packages: description: name: permission_handler_html sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.1.3+5" permission_handler_platform_interface: @@ -429,7 +791,7 @@ packages: description: name: permission_handler_platform_interface sha256: e9c8eadee926c4532d0305dff94b85bf961f16759c3af791486613152af4b4f9 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.2.3" permission_handler_windows: @@ -437,15 +799,23 @@ packages: description: name: permission_handler_windows sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "6.0.2" platform: dependency: transitive description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.1.6" plugin_platform_interface: @@ -453,23 +823,55 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.8" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.5.1" + posix: + dependency: transitive + description: + name: posix + sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "6.0.1" provider: dependency: transitive description: name: provider sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.1.2" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.1.5" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.4.0" recase: dependency: transitive description: name: recase sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.1.0" record: @@ -477,7 +879,7 @@ packages: description: name: record sha256: "8cb57763d954624fbc673874930c6f1ceca3baaf9bfee24b25da6fd451362394" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.2.0" record_android: @@ -485,7 +887,7 @@ packages: description: name: record_android sha256: "0b4739a2502fff402b0ac0ff1d6b2740854d116d78e06a4a16b3989821f84446" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.3.0" record_darwin: @@ -493,7 +895,7 @@ packages: description: name: record_darwin sha256: e487eccb19d82a9a39cd0126945cfc47b9986e0df211734e2788c95e3f63c82c - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.2" record_linux: @@ -501,7 +903,7 @@ packages: description: name: record_linux sha256: "74d41a9ebb1eb498a38e9a813dd524e8f0b4fdd627270bda9756f437b110a3e3" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.7.2" record_platform_interface: @@ -509,7 +911,7 @@ packages: description: name: record_platform_interface sha256: "8a575828733d4c3cb5983c914696f40db8667eab3538d4c41c50cbb79e722ef4" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.0" record_web: @@ -517,7 +919,7 @@ packages: description: name: record_web sha256: "10cb041349024ce4256e11dd35874df26d8b45b800678f2f51fd1318901adc64" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.4" record_windows: @@ -525,7 +927,7 @@ packages: description: name: record_windows sha256: "7bce0ac47454212ca8bfa72791d8b6a951f2fb0d4b953b64443c014227f035b4" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.4" rxdart: @@ -533,20 +935,92 @@ packages: description: name: rxdart sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.28.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "688ee90fbfb6989c980254a56cb26ebe9bb30a3a2dff439a78894211f73de67a" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.5.1" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "650584dcc0a39856f369782874e562efd002a9c94aec032412c9eb81419cce1f" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.4.4" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.5.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.4.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.4.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.4.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter source: sdk - version: "0.0.0" + version: "0.0.99" source_span: dependency: transitive description: name: source_span sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.10.0" sprintf: @@ -554,71 +1028,95 @@ packages: description: name: sprintf sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "7.0.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" - url: "https://pub.dev" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "1.12.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.2" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" - url: "https://pub.dev" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "1.3.0" + version: "1.2.0" synchronized: dependency: transitive description: name: synchronized sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.3.0+3" tau_web: dependency: transitive description: name: tau_web - sha256: c612cd3dcd9b7aa3472c0272bf3531fc232cd80e53ed7d7388b77dd541720cd6 - url: "https://pub.dev" + sha256: "81c8a0dc264f87db84678e5957dd1e4ccc015047fdea0f2cdd86d91c3c8a838e" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "0.0.14-alpha.4" + version: "0.0.14-alpha.5" term_glyph: dependency: transitive description: name: term_glyph sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" - url: "https://pub.dev" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "0.7.3" + version: "0.7.2" + time: + dependency: transitive + description: + name: time + sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "2.1.5" + timing: + dependency: transitive + description: + name: timing + sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.0.2" typed_data: dependency: transitive description: name: typed_data sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.4.0" uuid: @@ -626,31 +1124,55 @@ packages: description: name: uuid sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.5.1" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.1.13" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "1.1.16" vector_math: dependency: transitive description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b - url: "https://pub.dev" + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "14.2.5" + watcher: + dependency: transitive + description: + name: watcher + sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "14.3.0" + version: "1.1.1" web: dependency: transitive description: name: web sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.0" web_socket: @@ -658,7 +1180,7 @@ packages: description: name: web_socket sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.1.6" web_socket_channel: @@ -666,7 +1188,7 @@ packages: description: name: web_socket_channel sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.2" xdg_directories: @@ -674,9 +1196,25 @@ packages: description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.dev" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "6.5.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + source: hosted + version: "3.1.3" sdks: - dart: ">=3.6.0 <4.0.0" + dart: ">=3.5.4 <4.0.0" flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml index 2f911ed..f1d4fff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,7 +31,8 @@ dependencies: flutter: sdk: flutter - + flutter_localizations: + sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 @@ -40,13 +41,20 @@ dependencies: logger: ^2.5.0 path_provider: ^2.1.5 record: ^5.2.0 - intl: ^0.20.2 + intl: ^0.19.0 web_socket_channel: ^3.0.2 http: ^1.3.0 get: ^4.6.6 json_annotation: ^4.9.0 audioplayers: ^6.1.1 audio_waveforms: ^1.2.0 + gap: ^3.0.1 + flutter_gen_runner: ^5.9.0 + build_runner: ^2.4.13 + flutter_easyloading: ^3.0.5 + flutter_keyboard_visibility: ^6.0.0 + shared_preferences: ^2.5.1 + dio: ^5.8.0+1 dev_dependencies: flutter_test: @@ -58,6 +66,7 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^5.0.0 + intl_utils: ^2.8.5 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -70,9 +79,9 @@ flutter: # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + assets: + - assets/icon/ + - assets/img/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images