diff --git a/.github/workflows/build_windows_app.yml b/.github/workflows/build_windows_app.yml index c9855574..61ceccce 100644 --- a/.github/workflows/build_windows_app.yml +++ b/.github/workflows/build_windows_app.yml @@ -18,13 +18,14 @@ jobs: flutter-version: "3.13.2" # Set flutter version here - name: Build Windows app - run: flutter build windows --release + #run: flutter build windows --release + run: dart run msix:create --release -v --output-path build/windows/runner --output-name AIdea - - name: Copy dependencies - run: copy .\windows\sqlite3.dll .\build\windows\runner\Release\ + # - name: Copy dependencies + # run: copy .\windows\sqlite3.dll .\build\windows\runner\Release\ - name: Upload artifact uses: actions/upload-artifact@v2 with: name: aidea - path: build/windows/runner/Release \ No newline at end of file + path: build/windows/runner/AIdea.msix \ No newline at end of file diff --git a/Makefile b/Makefile index a75fbeb1..0100deef 100644 --- a/Makefile +++ b/Makefile @@ -11,12 +11,11 @@ build-all: build-android ipa build-android: flutter build apk --release --no-tree-shake-icons # open build/app/outputs/flutter-apk - mv build/app/outputs/flutter-apk/app-release.apk /Users/mylxsw/ResilioSync/ResilioSync/临时文件/ + mv build/app/outputs/flutter-apk/app-release.apk /Users/mylxsw/ResilioSync/ResilioSync/临时文件/aidea-release.apk build-macos: flutter build macos --no-tree-shake-icons --release codesign -f -s "Developer ID Application: YIYAO GUAN (N95437SZ2A)" build/macos/Build/Products/Release/AIdea.app - open build/macos/Build/Products/Release/ build-appimage: flutter build linux --no-tree-shake-icons --release @@ -27,6 +26,22 @@ build-appimage: cp askaide.desktop aidea_app.AppDir/ appimagetool aidea_app.AppDir/ +build-dmg: build-macos + rm -fr build/macos/Build/Products/Package + mkdir -p build/macos/Build/Products/Package && cp -r build/macos/Build/Products/Release/AIdea.app build/macos/Build/Products/Package + create-dmg --volname "AIdea Installer" \ + --volicon "install.icns" \ + --background "assets/background-discovery.png" \ + --window-pos 200 120 \ + --window-size 600 320 \ + --icon-size 100 \ + --icon "AIdea.app" 170 130 \ + --hide-extension "AIdea.app" \ + --app-drop-link 430 130 \ + "build/macos/Build/Products/Package/AIdea-Installer.dmg" \ + "build/macos/Build/Products/Package" + open build/macos/Build/Products/Package/ + build-web: flutter build web --web-renderer canvaskit --release --dart-define=FLUTTER_WEB_CANVASKIT_URL=https://resources.aicode.cc/canvaskit/ cd scripts && go run main.go ../build/web/main.dart.js && cd .. @@ -45,4 +60,4 @@ deploy-web: build-web ssh huawei-1 "cd /data/webroot && tar -zxvf web.tar.gz && rm -rf web.tar.gz app && mv web app" rm -fr build/web.tar.gz -.PHONY: run build-android build-macos ipa build-web-samehost build-web deploy-web +.PHONY: run build-android build-macos ipa build-web-samehost build-web deploy-web build-dmg diff --git a/build-win.bat b/build-win.bat new file mode 100644 index 00000000..03ee7ea7 --- /dev/null +++ b/build-win.bat @@ -0,0 +1 @@ +dart run msix:create --release -v --output-path build/windows/runner --output-name AIdea \ No newline at end of file diff --git a/install.icns b/install.icns new file mode 100644 index 00000000..b7bba57f Binary files /dev/null and b/install.icns differ diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6306382e..fd1f9b13 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -85,8 +85,9 @@ PODS: - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - record (0.0.1): + - record_darwin (1.0.0): - Flutter + - FlutterMacOS - screen_brightness_ios (0.1.0): - Flutter - SDWebImage (5.15.5): @@ -134,7 +135,7 @@ DEPENDENCIES: - media_kit_video (from `.symlinks/plugins/media_kit_video/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - - record (from `.symlinks/plugins/record/ios`) + - record_darwin (from `.symlinks/plugins/record_darwin/ios`) - screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) @@ -192,8 +193,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" - record: - :path: ".symlinks/plugins/record/ios" + record_darwin: + :path: ".symlinks/plugins/record_darwin/ios" screen_brightness_ios: :path: ".symlinks/plugins/screen_brightness_ios/ios" share_plus: @@ -228,25 +229,25 @@ SPEC CHECKSUMS: fluwx: e9e728cfdb80e82dac5f4ff974b1901a7939dcd0 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 - in_app_purchase_storekit: 4fb7ee9e824b1f09107fbfbbce8c4b276366dc43 + in_app_purchase_storekit: 9e9931234f0adcf71ae323f8c83785b96030edf1 libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1 media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 - record: cae05d8dd3cdb1dea3511b20e5a5811a1ae00d0d + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + record_darwin: 1f6619f2abac4d1ca91d3eeab038c980d76f1517 screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625 SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe SDWebImageWebPCoder: 295a6573c512f54ad2dd58098e64e17dcf008499 share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5 - shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440 - sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a + sqflite: 50a33e1d72bd59ee092a519a35d107502757ebed SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f tobias: 2aded9b83e3663b907360a800d8e3c13284f25c5 - url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 + url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812 volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9 wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47 WechatOpenSDK-XCFramework: acdeeda129efbef9532bca8a10c24e1b4b8c7d69 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6fd109c6..9c81ed94 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -472,8 +472,6 @@ "-framework", "\"path_provider_foundation\"", "-framework", - "\"record\"", - "-framework", "\"share_plus\"", "-framework", "\"shared_preferences_foundation\"", @@ -701,8 +699,6 @@ "-framework", "\"path_provider_foundation\"", "-framework", - "\"record\"", - "-framework", "\"share_plus\"", "-framework", "\"shared_preferences_foundation\"", @@ -824,8 +820,6 @@ "-framework", "\"path_provider_foundation\"", "-framework", - "\"record\"", - "-framework", "\"share_plus\"", "-framework", "\"shared_preferences_foundation\"", diff --git a/lib/bloc/bloc_manager.dart b/lib/bloc/bloc_manager.dart index b7643a0d..cf782dc0 100644 --- a/lib/bloc/bloc_manager.dart +++ b/lib/bloc/bloc_manager.dart @@ -1,3 +1,5 @@ +// ignore_for_file: must_call_super + import 'package:askaide/bloc/chat_message_bloc.dart'; import 'package:askaide/helper/lru.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/lib/helper/constant.dart b/lib/helper/constant.dart index 9372331a..c90f9cb9 100644 --- a/lib/helper/constant.dart +++ b/lib/helper/constant.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; // 客户端应用版本号 -const clientVersion = '1.0.11'; +const clientVersion = '1.0.12'; // 本地数据库版本号 const databaseVersion = 26; @@ -12,6 +12,8 @@ const settingAPIServerToken = 'api-token'; const settingUserInfo = 'user-info'; const settingUsingGuestMode = 'using-guest-mode'; +const settingForceShowLab = 'force-show-lab'; + const chatAnywhereModel = 'openai:gpt-3.5-turbo'; const chatAnywhereRoomId = 1; diff --git a/lib/helper/env.dart b/lib/helper/env.dart index 553e13f8..0346c798 100644 --- a/lib/helper/env.dart +++ b/lib/helper/env.dart @@ -1,7 +1,3 @@ -import 'dart:io' show Platform; - -import 'package:askaide/helper/platform.dart'; - /// 默认 API 服务器地址 /// 注意:当你使用自己的服务器时,请修改该地址为你自己的服务器地址 const defaultAPIServerURL = 'https://ai-api.aicode.cc'; @@ -20,14 +16,3 @@ String get apiServerURL { return url; } - -String get getHomePath { - Map envVars = Platform.environment; - if (PlatformTool.isMacOS() || PlatformTool.isLinux()) { - return '${envVars['HOME'] ?? ''}/.aidea'; - } else if (PlatformTool.isWindows()) { - return '${envVars['UserProfile'] ?? ''}/.aidea'; - } - - return '.aidea'; -} diff --git a/lib/helper/logger.dart b/lib/helper/logger.dart index 6132dbb4..90eafd32 100644 --- a/lib/helper/logger.dart +++ b/lib/helper/logger.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:askaide/helper/env.dart'; +import 'package:askaide/helper/path.dart'; import 'package:askaide/helper/platform.dart'; import 'package:logger/logger.dart' as logger; @@ -17,7 +17,7 @@ class Logger { logger.ConsoleOutput(), if (!PlatformTool.isWeb()) logger.FileOutput( - file: File('$getHomePath/aidea.log'), + file: File(PathHelper().getLogfilePath), overrideExisting: true, ), ], diff --git a/lib/helper/path.dart b/lib/helper/path.dart new file mode 100644 index 00000000..a9b4e2ee --- /dev/null +++ b/lib/helper/path.dart @@ -0,0 +1,79 @@ +import 'dart:io' show Directory, Platform; +import 'package:askaide/helper/platform.dart'; +import 'package:path_provider/path_provider.dart'; + +class PathHelper { + late final String cachePath; + late final String documentsPath; + late final String supportPath; + + init() async { + try { + cachePath = + (await getApplicationCacheDirectory()).path.replaceAll('\\', '/'); + } catch (e) { + cachePath = ''; + } + + try { + documentsPath = + (await getApplicationDocumentsDirectory()).path.replaceAll('\\', '/'); + } catch (e) { + documentsPath = ''; + } + + try { + supportPath = + (await getApplicationSupportDirectory()).path.replaceAll('\\', '/'); + } catch (e) { + supportPath = ''; + } + + // 确保 .aidea 目录存在 + try { + Directory(getHomePath).create(recursive: true); + } catch (e) { + print('创建 $getHomePath 目录失败: $e'); + } + } + + String get getHomePath { + Map envVars = Platform.environment; + if (PlatformTool.isMacOS() || PlatformTool.isLinux()) { + return '${envVars['HOME'] ?? ''}/.aidea'.replaceAll('\\', '/'); + } else if (PlatformTool.isWindows()) { + return '${envVars['UserProfile'] ?? ''}/.aidea'.replaceAll('\\', '/'); + } else if (PlatformTool.isAndroid() || PlatformTool.isIOS()) { + return '$documentsPath/.aidea'.replaceAll('\\', '/'); + } + + return '.aidea'; + } + + String get getLogfilePath { + return '$getHomePath/aidea.log'; + } + + String get getCachePath { + return getHomePath; + } + + /// 单例 + static final PathHelper _instance = PathHelper._internal(); + PathHelper._internal(); + + factory PathHelper() { + return _instance; + } + + Map toMap() { + return { + 'cachePath': cachePath, + 'cachePathReal': getCachePath, + 'documentsPath': documentsPath, + 'supportPath': supportPath, + 'homePath': getHomePath, + 'logfilePath': getLogfilePath, + }; + } +} diff --git a/lib/lang/lang.dart b/lib/lang/lang.dart index 25079a8c..e855fde0 100644 --- a/lib/lang/lang.dart +++ b/lib/lang/lang.dart @@ -338,7 +338,7 @@ mixin AppLocale { keywordsSeparatedByCommas: '你想象画面的关键词,以逗号隔开。', originalImage: '原始图片', superResolution: '高清修复', - colorizeImage: '图片上色', + colorizeImage: '旧照片上色', errorLog: '故障诊断', report: '上报', latestVersion: '当前已是最新版本', diff --git a/lib/main.dart b/lib/main.dart index 58818639..53d1532d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,5 @@ +import 'package:askaide/helper/path.dart'; +import 'package:askaide/page/creative_island/draw/artistic_wordart.dart'; import 'package:path/path.dart'; import 'package:askaide/bloc/account_bloc.dart'; @@ -19,7 +21,7 @@ import 'package:askaide/helper/platform.dart'; import 'package:askaide/lang/lang.dart'; import 'package:askaide/data/migrate.dart'; import 'package:askaide/page/balance/quota_usage_details.dart'; -import 'package:askaide/page/creative_island/draw/artistic_text.dart'; +import 'package:askaide/page/creative_island/draw/artistic_qr.dart'; import 'package:askaide/page/setting/account_security.dart'; import 'package:askaide/page/app_scaffold.dart'; import 'package:askaide/page/lab/avatar_selector.dart'; @@ -104,13 +106,14 @@ import 'package:askaide/helper/http.dart' as httpx; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:media_kit/media_kit.dart'; -import 'package:askaide/helper/env.dart'; - void main() async { WidgetsFlutterBinding.ensureInitialized(); MediaKit.ensureInitialized(); httpx.HttpClient.init(); + // 初始化路径,获取到系统相关的文档、缓存目录 + await PathHelper().init(); + FlutterError.onError = (FlutterErrorDetails details) { if (details.library == 'rendering library' || details.library == 'image resource service') { @@ -133,7 +136,7 @@ void main() async { PlatformTool.isMacOS()) { sqfliteFfiInit(); databaseFactory = databaseFactoryFfi; - var path = absolute(join(getHomePath, 'databases')); + var path = absolute(join(PathHelper().getHomePath, 'databases')); databaseFactory.setDatabasesPath(path); } } @@ -714,7 +717,7 @@ class MyApp extends StatefulWidget { providers: [ BlocProvider.value(value: galleryBloc), ], - child: ArtisticTextScreen( + child: ArtisticQRScreen( setting: settingRepo, galleryCopyId: int.tryParse( state.queryParameters['gallery_copy_id'] ?? '', @@ -726,6 +729,26 @@ class MyApp extends StatefulWidget { ), ), ), + GoRoute( + name: 'creative-artistic-wordart', + path: '/creative-draw/artistic-wordart', + parentNavigatorKey: _shellNavigatorKey, + pageBuilder: (context, state) => transitionResolver( + MultiBlocProvider( + providers: [ + BlocProvider.value(value: galleryBloc), + ], + child: ArtisticWordArtScreen( + setting: settingRepo, + galleryCopyId: int.tryParse( + state.queryParameters['gallery_copy_id'] ?? '', + ), + id: state.queryParameters['id']!, + note: state.queryParameters['note'], + ), + ), + ), + ), GoRoute( name: 'creative-island-history-all', path: '/creative-island/history', diff --git a/lib/page/component/chat/chat_share.dart b/lib/page/component/chat/chat_share.dart index 8f27eadd..af1fff10 100644 --- a/lib/page/component/chat/chat_share.dart +++ b/lib/page/component/chat/chat_share.dart @@ -1,7 +1,10 @@ +import 'dart:io'; + import 'package:askaide/helper/ability.dart'; import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/helper.dart'; import 'package:askaide/helper/image.dart'; +import 'package:askaide/helper/logger.dart'; import 'package:askaide/helper/platform.dart'; import 'package:askaide/lang/lang.dart'; import 'package:askaide/page/component/chat/file_upload.dart'; @@ -134,16 +137,37 @@ class _ChatShareScreenState extends State { showSuccessMessage('图片保存成功'); } else { - FileSaver.instance - .saveFile( - name: randomId(), - bytes: data, - ext: 'png', - mimeType: MimeType.png, - ) - .then((value) { - showSuccessMessage('文件保存成功'); - }); + if (PlatformTool.isWindows()) { + FileSaver.instance + .saveAs( + name: randomId(), + bytes: data, + ext: '.png', + mimeType: MimeType.png, + ) + .then((value) async { + if (value == null) { + return ; + } + + await File(value).writeAsBytes(data); + + Logger.instance.d('文件保存成功: $value'); + showSuccessMessage('文件保存成功'); + }); + } else { + FileSaver.instance + .saveFile( + name: randomId(), + bytes: data, + ext: 'png', + mimeType: MimeType.png, + ) + .then((value) { + showSuccessMessage('文件保存成功'); + }); + } + } } } finally { diff --git a/lib/page/component/chat/voice_record.dart b/lib/page/component/chat/voice_record.dart index b13e8ed0..5ff3e3ff 100644 --- a/lib/page/component/chat/voice_record.dart +++ b/lib/page/component/chat/voice_record.dart @@ -2,8 +2,12 @@ import 'dart:async'; import 'dart:io'; import 'package:askaide/helper/haptic_feedback.dart'; +import 'package:askaide/helper/helper.dart'; import 'package:askaide/helper/model_resolver.dart'; +import 'package:askaide/helper/path.dart'; +import 'package:askaide/helper/platform.dart'; import 'package:askaide/lang/lang.dart'; +import 'package:askaide/page/component/chat/markdown.dart'; import 'package:askaide/page/component/loading.dart'; import 'package:askaide/page/component/dialog.dart'; import 'package:askaide/page/component/theme/custom_theme.dart'; @@ -11,7 +15,9 @@ import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localization/flutter_localization.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; +import 'package:quickalert/quickalert.dart'; import 'package:record/record.dart'; +import 'package:url_launcher/url_launcher_string.dart'; class VoiceRecord extends StatefulWidget { final Function(String text) onFinished; @@ -25,7 +31,7 @@ class VoiceRecord extends StatefulWidget { class _VoiceRecordState extends State { var _voiceRecording = false; - final record = Record(); + final record = AudioRecorder(); DateTime? _voiceStartTime; Timer? _timer; var _millSeconds = 0; @@ -43,6 +49,7 @@ class _VoiceRecordState extends State { @override void dispose() { _timer?.cancel(); + record.dispose(); super.dispose(); } @@ -72,6 +79,31 @@ class _VoiceRecordState extends State { const SizedBox(height: 10), GestureDetector( onLongPressStart: (details) async { + if (PlatformTool.isWeb()) { + showCustomBeautyDialog( + context, + type: QuickAlertType.warning, + confirmBtnText: AppLocale.gotIt.getString(context), + showCancelBtn: false, + title: '温馨提示', + child: Markdown( + data: + 'Web 端暂不支持语音输入,敬请期待。\n\n要体验完整功能,您可[点击这里下载 AIdea APP](https://aidea.aicode.cc)。', + onUrlTap: (value) { + launchUrlString( + value, + mode: LaunchMode.externalApplication, + ); + }, + textStyle: TextStyle( + fontSize: 14, + color: customColors.dialogDefaultTextColor, + ), + ), + ); + return; + } + widget.onStart(); if (await record.hasPermission()) { @@ -84,9 +116,12 @@ class _VoiceRecordState extends State { }); // Start recording await record.start( - encoder: AudioEncoder.aacLc, // by default - bitRate: 128000, // by default - samplingRate: 44100, // by default + RecordConfig( + encoder: PlatformTool.isWindows() || PlatformTool.isIOS() + ? AudioEncoder.aacLc + : AudioEncoder.wav, + ), + path: "${PathHelper().getCachePath}/${randomId()}.m4a", ); setState(() { @@ -135,7 +170,7 @@ class _VoiceRecordState extends State { child: CircleAvatar( backgroundColor: _voiceRecording ? customColors.linkColor - : customColors.linkColor!.withAlpha(200), + : customColors.linkColor?.withAlpha(200), child: const Icon( Icons.mic, size: 50, @@ -154,6 +189,21 @@ class _VoiceRecordState extends State { ); } + deleteTempFile(String path) { + // 删除临时文件 + if (!path.startsWith('blob:')) { + try { + File.fromUri(Uri.parse(path)).deleteSync(); + } catch (e) { + try { + File(path).deleteSync(); + } catch (e) { + // ignore + } + } + } + } + Future onRecordStop() async { _timer?.cancel(); @@ -163,18 +213,20 @@ class _VoiceRecordState extends State { return; } + resPath = resPath.replaceAll('\\', '/'); + final voiceDuration = DateTime.now().difference(_voiceStartTime!).inSeconds; if (voiceDuration < 1) { showErrorMessage('说话时间太短'); _voiceStartTime = null; - File.fromUri(Uri.parse(resPath)).delete(); + deleteTempFile(resPath); return; } if (voiceDuration > 60) { showErrorMessage('说话时间太长'); _voiceStartTime = null; - File.fromUri(Uri.parse(resPath)).delete(); + deleteTempFile(resPath); return; } @@ -191,17 +243,20 @@ class _VoiceRecordState extends State { ); try { - final audioFile = File.fromUri(Uri.parse(resPath)); + File audioFile; + try { + audioFile = File.fromUri(Uri.parse(resPath)); + } catch (e) { + audioFile = File(resPath); + } + widget.onFinished(await ModelResolver.instance.audioToText(audioFile)); } catch (e) { // ignore: use_build_context_synchronously showErrorMessageEnhanced(context, e); } finally { cancel(); - // 删除临时文件 - if (!resPath.startsWith('blob:')) { - File.fromUri(Uri.parse(resPath)).delete(); - } + deleteTempFile(resPath); } } } diff --git a/lib/page/component/dialog.dart b/lib/page/component/dialog.dart index 62e77165..2063102e 100644 --- a/lib/page/component/dialog.dart +++ b/lib/page/component/dialog.dart @@ -652,7 +652,9 @@ openTextFieldDialog( }, ).whenComplete(() { GlobalEvent().emit('showBottomNavigatorBar'); - controller.dispose(); + Future.delayed(const Duration(seconds: 1), () { + controller.dispose(); + }); }); } diff --git a/lib/page/component/enhanced_textfield.dart b/lib/page/component/enhanced_textfield.dart index 3759777c..7a027862 100644 --- a/lib/page/component/enhanced_textfield.dart +++ b/lib/page/component/enhanced_textfield.dart @@ -112,22 +112,30 @@ class EnhancedTextField extends StatefulWidget { class _EnhancedTextFieldState extends State { var textLength = 0; + late final Function() listener; + @override void initState() { super.initState(); - widget.controller?.addListener(() { + listener = () { if (mounted) { setState(() { textLength = widget.controller!.text.length; }); } - }); + }; + + if (widget.showCounter) { + widget.controller?.addListener(listener); + } } @override void dispose() { - widget.controller?.removeListener(() {}); + if (widget.showCounter) { + widget.controller?.removeListener(listener); + } super.dispose(); } diff --git a/lib/page/component/gallery_item_share.dart b/lib/page/component/gallery_item_share.dart index 3bd0596e..96cc4e57 100644 --- a/lib/page/component/gallery_item_share.dart +++ b/lib/page/component/gallery_item_share.dart @@ -1,6 +1,9 @@ +import 'dart:io'; + import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/helper.dart'; import 'package:askaide/helper/image.dart'; +import 'package:askaide/helper/logger.dart'; import 'package:askaide/helper/platform.dart'; import 'package:askaide/lang/lang.dart'; import 'package:askaide/page/component/column_block.dart'; @@ -120,16 +123,38 @@ class _GalleryItemShareScreenState extends State { showSuccessMessage('图片保存成功'); } else { - FileSaver.instance - .saveFile( - name: randomId(), - bytes: data, - ext: 'png', - mimeType: MimeType.png, - ) - .then((value) { - showSuccessMessage('文件保存成功'); - }); + if (PlatformTool.isWindows()) { + FileSaver.instance + .saveAs( + name: randomId(), + bytes: data, + ext: '.png', + mimeType: MimeType.png, + ) + .then((value) async { + if (value == null) { + return ; + } + + await File(value).writeAsBytes(data); + + Logger.instance.d('文件保存成功: $value'); + showSuccessMessage('文件保存成功'); + }); + } else { + FileSaver.instance + .saveFile( + name: randomId(), + bytes: data, + ext: 'png', + mimeType: MimeType.png, + ) + .then((value) { + Logger.instance.d('文件保存成功: $value'); + showSuccessMessage('文件保存成功'); + }); + } + } } } finally { diff --git a/lib/page/component/image_action.dart b/lib/page/component/image_action.dart index b54e0530..323315c2 100644 --- a/lib/page/component/image_action.dart +++ b/lib/page/component/image_action.dart @@ -144,7 +144,7 @@ Widget actionsBuilder( const SizedBox(height: 10), if (itemsMap.containsKey('image-colorize')) Button( - title: '图片上色', + title: '旧照片上色', icon: Icon( Icons.palette_outlined, size: 16, diff --git a/lib/page/component/image_preview.dart b/lib/page/component/image_preview.dart index 3147ca5e..4719c3ef 100644 --- a/lib/page/component/image_preview.dart +++ b/lib/page/component/image_preview.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/helper.dart'; import 'package:askaide/helper/image.dart'; @@ -379,16 +381,38 @@ void openImagePreviewDialog( mimeType = MimeType.other; } - FileSaver.instance + if (PlatformTool.isWindows()) { + FileSaver.instance + .saveAs( + name: filenameWithoutExt(saveFile.path.split('/').last), + filePath: saveFile.path, + ext: '.$ext', + mimeType: mimeType, + ) + .then((value) async { + if (value == null) { + return ; + } + + await File(value).writeAsBytes(await saveFile.readAsBytes()); + + Logger.instance.d('文件保存成功: $value'); + showSuccessMessage('文件保存成功'); + }); + } else { + FileSaver.instance .saveFile( - name: filenameWithoutExt(saveFile.path.split('/').last), - filePath: saveFile.path, - ext: ext, - mimeType: mimeType, - ) - .then((value) { - showSuccessMessage('文件保存成功'); - }); + name: filenameWithoutExt(saveFile.path.split('/').last), + filePath: saveFile.path, + ext: ext, + mimeType: mimeType, + ) + .then((value) { + Logger.instance.d('文件保存成功: $value'); + showSuccessMessage('文件保存成功'); + }); + } + } } catch (e) { // ignore: use_build_context_synchronously diff --git a/lib/page/component/video_player.dart b/lib/page/component/video_player.dart index a4821655..8ddff3e4 100644 --- a/lib/page/component/video_player.dart +++ b/lib/page/component/video_player.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:askaide/helper/helper.dart'; import 'package:askaide/helper/logger.dart'; import 'package:askaide/helper/platform.dart'; @@ -129,17 +131,37 @@ class _VideoPlayerState extends State { } else { var ext = saveFile.path.toLowerCase().split('.').last; - FileSaver.instance - .saveFile( - name: - filenameWithoutExt(saveFile.path.split('/').last), - filePath: saveFile.path, - ext: ext, - mimeType: MimeType.mpeg, - ) - .then((value) { - showSuccessMessage('文件保存成功'); - }); + if (PlatformTool.isWindows()) { + FileSaver.instance + .saveAs( + name: filenameWithoutExt(saveFile.path.split('/').last), + filePath: saveFile.path, + ext: '.$ext', + mimeType: MimeType.mpeg, + ) + .then((value) async { + if (value == null) { + return ; + } + + await File(value).writeAsBytes(await saveFile.readAsBytes()); + + Logger.instance.d('文件保存成功: $value'); + showSuccessMessage('文件保存成功'); + }); + } else { + FileSaver.instance + .saveFile( + name: + filenameWithoutExt(saveFile.path.split('/').last), + filePath: saveFile.path, + ext: ext, + mimeType: MimeType.mpeg, + ) + .then((value) { + showSuccessMessage('文件保存成功'); + }); + } } } catch (e) { // ignore: use_build_context_synchronously diff --git a/lib/page/creative_island/draw/artistic_text.dart b/lib/page/creative_island/draw/artistic_qr.dart similarity index 98% rename from lib/page/creative_island/draw/artistic_text.dart rename to lib/page/creative_island/draw/artistic_qr.dart index 5120ac14..0651b8d3 100644 --- a/lib/page/creative_island/draw/artistic_text.dart +++ b/lib/page/creative_island/draw/artistic_qr.dart @@ -31,14 +31,14 @@ import 'package:flutter_localization/flutter_localization.dart'; import 'package:go_router/go_router.dart'; import 'package:quickalert/models/quickalert_type.dart'; -class ArtisticTextScreen extends StatefulWidget { +class ArtisticQRScreen extends StatefulWidget { final SettingRepository setting; final int? galleryCopyId; final String type; final String id; final String? note; - const ArtisticTextScreen({ + const ArtisticQRScreen({ super.key, required this.id, required this.setting, @@ -48,10 +48,10 @@ class ArtisticTextScreen extends StatefulWidget { }); @override - State createState() => _ArtisticTextScreenState(); + State createState() => _ArtisticQRScreenState(); } -class _ArtisticTextScreenState extends State { +class _ArtisticQRScreenState extends State { bool enableAIRewrite = false; bool showAdvancedOptions = false; @@ -154,7 +154,7 @@ class _ArtisticTextScreenState extends State { return Scaffold( appBar: AppBar( title: Text( - widget.type == 'qr' ? '艺术二维码' : '艺术字', + widget.type == 'qr' ? '艺术二维码' : '图文融合', style: const TextStyle(fontSize: CustomSize.appBarTitleSize), ), centerTitle: true, diff --git a/lib/page/creative_island/draw/artistic_wordart.dart b/lib/page/creative_island/draw/artistic_wordart.dart new file mode 100644 index 00000000..d866aef9 --- /dev/null +++ b/lib/page/creative_island/draw/artistic_wordart.dart @@ -0,0 +1,540 @@ +import 'dart:math'; + +import 'package:askaide/helper/ability.dart'; +import 'package:askaide/helper/cache.dart'; +import 'package:askaide/helper/haptic_feedback.dart'; +import 'package:askaide/lang/lang.dart'; +import 'package:askaide/page/component/background_container.dart'; +import 'package:askaide/page/component/column_block.dart'; +import 'package:askaide/page/component/dialog.dart'; +import 'package:askaide/page/component/enhanced_button.dart'; +import 'package:askaide/page/component/enhanced_input.dart'; +import 'package:askaide/page/component/enhanced_textfield.dart'; +import 'package:askaide/page/component/global_alert.dart'; +import 'package:askaide/page/component/item_selector_search.dart'; +import 'package:askaide/page/component/loading.dart'; +import 'package:askaide/page/component/prompt_tags_selector.dart'; +import 'package:askaide/page/component/theme/custom_size.dart'; +import 'package:askaide/page/component/theme/custom_theme.dart'; +import 'package:askaide/page/creative_island/draw/components/artistic_style_selector.dart'; +import 'package:askaide/page/creative_island/draw/components/content_preview.dart'; +import 'package:askaide/page/creative_island/draw/draw_result.dart'; +import 'package:askaide/repo/api/creative.dart'; +import 'package:askaide/repo/api_server.dart'; +import 'package:askaide/repo/model/misc.dart'; +import 'package:askaide/repo/settings_repo.dart'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_localization/flutter_localization.dart'; +import 'package:go_router/go_router.dart'; +import 'package:quickalert/models/quickalert_type.dart'; + +class ArtisticWordArtScreen extends StatefulWidget { + final SettingRepository setting; + final int? galleryCopyId; + final String id; + final String? note; + + const ArtisticWordArtScreen({ + super.key, + required this.id, + required this.setting, + this.galleryCopyId, + this.note, + }); + + @override + State createState() => _ArtisticWordArtScreenState(); +} + +class _ArtisticWordArtScreenState extends State { + bool showAdvancedOptions = false; + + CreativeIslandCapacity? capacity; + + CreativeIslandArtisticStyle? selectedStyle; + CreativeIslandArtisticStyle? selectedFonts; + + /// 是否停止周期性查询任务执行状态 + var stopPeriodQuery = false; + + int generationImageCount = 1; + + TextEditingController promptController = TextEditingController(); + TextEditingController textController = TextEditingController(); + + @override + void dispose() { + promptController.dispose(); + textController.dispose(); + super.dispose(); + } + + @override + void initState() { + APIServer() + .creativeIslandCapacity(mode: 'artistic-text', id: widget.id) + .then((cap) { + setState(() { + capacity = cap; + }); + + if (widget.galleryCopyId != null && widget.galleryCopyId! > 0) { + APIServer() + .creativeGalleryItem(id: widget.galleryCopyId!) + .then((response) { + final gallery = response.item; + if (gallery.prompt != null && gallery.prompt!.isNotEmpty) { + promptController.text = gallery.prompt!; + } + + if (gallery.metaMap['real_prompt'] != null && + gallery.metaMap['real_prompt'] != '') { + promptController.text = gallery.metaMap['real_prompt']!; + } + + setState(() {}); + }); + } + }); + + if (widget.note != null) { + Cache() + .boolGet(key: 'creative:tutorials:artistic-text:dialog') + .then((show) { + if (!show) { + return; + } + + openDefaultTutorials(onConfirm: () { + Cache().setBool( + key: 'creative:tutorials:artistic-text:dialog', + value: false, + duration: const Duration(days: 30), + ); + }); + }); + } + + super.initState(); + } + + @override + Widget build(BuildContext context) { + final customColors = Theme.of(context).extension()!; + return Scaffold( + appBar: AppBar( + title: const Text( + '艺术字', + style: TextStyle(fontSize: CustomSize.appBarTitleSize), + ), + centerTitle: true, + leading: IconButton( + onPressed: () { + context.pop(); + }, + icon: const Icon(Icons.arrow_back_ios), + ), + toolbarHeight: CustomSize.toolbarHeight, + backgroundColor: customColors.backgroundContainerColor, + actions: [ + if (widget.note != null) + IconButton( + onPressed: () { + openDefaultTutorials(); + }, + icon: const Icon(Icons.help_outline), + ) + ], + ), + backgroundColor: customColors.backgroundContainerColor, + body: BackgroundContainer( + setting: widget.setting, + enabled: true, + maxWidth: CustomSize.smallWindowSize, + child: Column( + children: [ + if (Ability().showGlobalAlert) + const GlobalAlert(pageKey: 'creative_create'), + Expanded( + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 10, vertical: 10), + height: double.infinity, + child: SingleChildScrollView( + child: buildEditPanel(context, customColors), + ), + ), + ), + ], + ), + ), + ); + } + + void openDefaultTutorials({Function? onConfirm}) { + showBeautyDialog( + context, + type: QuickAlertType.info, + text: ' ${widget.note!}', + onConfirmBtnTap: () async { + onConfirm?.call(); + context.pop(); + }, + showCancelBtn: true, + confirmBtnText: AppLocale.gotIt.getString(context), + ); + } + + Widget buildEditPanel(BuildContext context, CustomColors customColors) { + return SafeArea( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ColumnBlock( + innerPanding: 10, + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), + children: [ + if (capacity != null && capacity!.artisticTextStyles.isNotEmpty) + ArtisticStyleSelector( + styles: capacity!.artisticTextStyles, + onSelected: (style) { + setState(() { + selectedStyle = style; + }); + }, + selectedStyle: selectedStyle, + ), + ], + ), + ColumnBlock( + innerPanding: 10, + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), + children: [ + EnhancedTextField( + labelPosition: LabelPosition.top, + labelText: '文字内容', + customColors: customColors, + controller: textController, + textAlignVertical: TextAlignVertical.top, + hintText: '要在画面中绘制的文字。', + maxLength: 20, + maxLines: 3, + minLines: 1, + showCounter: false, + ), + + // 生成内容 + ...buildPromptField(customColors), + ], + ), + + if (showAdvancedOptions) + ColumnBlock( + innerPanding: 10, + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), + children: [ + if (capacity != null && capacity!.artisticTextFonts.isNotEmpty) + ArtisticStyleSelector( + title: '文字字体', + styles: capacity!.artisticTextFonts, + onSelected: (style) { + setState(() { + selectedFonts = style; + }); + }, + selectedStyle: selectedFonts, + ), + // 图片数量 + EnhancedInput( + title: Text( + AppLocale.imageCount.getString(context), + style: TextStyle( + color: customColors.textfieldLabelColor, + fontSize: 16, + ), + ), + value: Text(generationImageCount.toString()), + onPressed: () { + openListSelectDialog( + context, + [ + SelectorItem( + const Text('1', textAlign: TextAlign.center), 1), + SelectorItem( + const Text('2', textAlign: TextAlign.center), 2), + SelectorItem( + const Text('3', textAlign: TextAlign.center), 3), + SelectorItem( + const Text('4', textAlign: TextAlign.center), 4), + ], + (value) { + setState(() { + generationImageCount = value.value; + }); + return true; + }, + heightFactor: 0.4, + value: generationImageCount, + ); + }, + ), + ], + ), + // 生成按钮 + const SizedBox(height: 20), + Row( + children: [ + EnhancedButton( + title: showAdvancedOptions + ? AppLocale.simpleMode.getString(context) + : AppLocale.professionalMode.getString(context), + width: 120, + backgroundColor: Colors.transparent, + color: customColors.weakLinkColor, + fontSize: 15, + icon: Icon( + showAdvancedOptions ? Icons.unfold_less : Icons.unfold_more, + color: customColors.weakLinkColor, + size: 15, + ), + onPressed: () { + setState(() { + showAdvancedOptions = !showAdvancedOptions; + }); + }, + ), + const SizedBox(width: 10), + Expanded( + flex: 1, + child: EnhancedButton( + title: AppLocale.generate.getString(context), + onPressed: onGenerate, + ), + ), + ], + ), + const SizedBox(height: 20), + ], + ), + ); + } + + List buildPromptField(CustomColors customColors) { + return [ + EnhancedTextField( + labelPosition: LabelPosition.top, + labelText: AppLocale.yourIdeas.getString(context), + customColors: customColors, + controller: promptController, + textAlignVertical: TextAlignVertical.top, + hintText: AppLocale.keywordsSeparatedByCommas.getString(context), + maxLines: 10, + minLines: 2, + maxLength: 460, + showCounter: false, + inputSelector: IconButton( + onPressed: () { + openModalBottomSheet( + context, + (context) { + return PromptTagsSelector( + selectedTags: selectedTags, + onSubmit: (tags) { + setState(() { + selectedTags = tags; + }); + context.pop(); + }, + ); + }, + heightFactor: 0.8, + useSafeArea: true, + ); + }, + icon: Icon( + Icons.lightbulb_outline, + color: customColors.linkColor, + size: 16, + ), + ), + middleWidget: Container( + width: double.infinity, + margin: const EdgeInsets.only(bottom: 30), + child: Wrap( + spacing: 3, + runSpacing: 3, + children: selectedTags + .map( + (e) => Tag( + name: e.name, + backgroundColor: customColors.linkColor, + textColor: Colors.white, + fontsize: 10, + onDeleted: () { + setState(() { + selectedTags.remove(e); + }); + }, + ), + ) + .toList(), + ), + ), + bottomButton: Row( + children: [ + Icon( + Icons.shuffle, + size: 13, + color: customColors.linkColor?.withAlpha(150), + ), + const SizedBox(width: 5), + Text( + AppLocale.random.getString(context), + style: TextStyle( + color: customColors.linkColor?.withAlpha(150), + fontSize: 13, + ), + ), + ], + ), + bottomButtonOnPressed: () async { + final examples = await APIServer().exampleByTag('artistic-wordart'); + if (examples.isEmpty) { + return; + } + + // 随机选取一个例子 + final example = examples[Random().nextInt(examples.length)]; + promptController.text = example.text; + }, + ), + ]; + } + + List selectedTags = []; + + void onGenerate() async { + FocusScope.of(context).requestFocus(FocusNode()); + HapticFeedbackHelper.mediumImpact(); + + final prompt = promptController.text.trim(); + if (prompt.isEmpty) { + showErrorMessage(AppLocale.contentIsRequired.getString(context)); + return; + } + + final text = textController.text.trim(); + if (text.isEmpty) { + showErrorMessage('文本内容不能为空'); + return; + } + + var params = { + 'prompt': prompt, + 'prompt_tags': selectedTags.map((e) => e.value).join(','), + 'gallery_copy_id': widget.galleryCopyId, + 'text': text, + 'type': 'word_art', + 'image_count': generationImageCount, + 'style_preset': selectedStyle?.id, + 'font_name': selectedFonts?.id, + }; + + final cancel = BotToast.showCustomLoading( + toastBuilder: (cancel) { + return const LoadingIndicator( + message: '思考中,请稍候...', + ); + }, + allowClick: false, + duration: const Duration(seconds: 15), + ); + + request(int waitDuration) async { + try { + final taskId = await APIServer() + .creativeIslandArtisticTextCompletionsAsyncV2(params); + + stopPeriodQuery = false; + + cancel(); + // ignore: use_build_context_synchronously + Navigator.push( + context, + MaterialPageRoute( + fullscreenDialog: true, + builder: (context) => DrawResultPage( + future: Future.delayed(const Duration(seconds: 10), () async { + return await queryCompletionTaskStatus( + taskId: taskId, + retryTimes: 0, + delaySeconds: 3, + params: params, + ); + }), + waitDuration: waitDuration, + ), + ), + ).whenComplete(() { + stopPeriodQuery = true; + }); + } catch (e) { + stopPeriodQuery = true; + cancel(); + // ignore: use_build_context_synchronously + showErrorMessageEnhanced(context, e); + } + } + + try { + request(45); + } catch (e) { + cancel(); + // ignore: use_build_context_synchronously + showErrorMessageEnhanced(context, e); + } + } + + Future queryCompletionTaskStatus({ + required String taskId, + required int retryTimes, + required int delaySeconds, + Map? params, + }) async { + if (retryTimes > 60) { + return Future.error(AppLocale.generateTimeout.getString(context)); + } + + final resp = await APIServer().asyncTaskStatus(taskId); + switch (resp.status) { + case 'success': + if (params != null && + resp.originImage != null && + resp.originImage != '') { + params['image'] = resp.originImage; + } + return IslandResult( + result: resp.resources ?? const [], + params: params, + ); + case 'failed': + return Future.error(resp.errors!.join(";")); + default: + if (stopPeriodQuery) { + // ignore: use_build_context_synchronously + return Future.error(AppLocale.generateTimeout.getString(context)); + } + + return await Future.delayed(Duration(seconds: delaySeconds), () async { + return await queryCompletionTaskStatus( + taskId: taskId, + retryTimes: retryTimes + 1, + delaySeconds: 3, + params: params, + ); + }); + } + } +} diff --git a/lib/page/creative_island/draw/components/artistic_style_selector.dart b/lib/page/creative_island/draw/components/artistic_style_selector.dart index 4d4ad1bd..6d158537 100644 --- a/lib/page/creative_island/draw/components/artistic_style_selector.dart +++ b/lib/page/creative_island/draw/components/artistic_style_selector.dart @@ -11,12 +11,14 @@ class ArtisticStyleSelector extends StatelessWidget { final List styles; final Function(CreativeIslandArtisticStyle style) onSelected; final CreativeIslandArtisticStyle? selectedStyle; + final String? title; const ArtisticStyleSelector({ super.key, required this.styles, required this.onSelected, this.selectedStyle, + this.title, }); @override @@ -24,7 +26,7 @@ class ArtisticStyleSelector extends StatelessWidget { final customColors = Theme.of(context).extension()!; return EnhancedInput( title: Text( - AppLocale.style.getString(context), + title ?? AppLocale.style.getString(context), style: TextStyle( color: customColors.textfieldLabelColor, fontSize: 16, diff --git a/lib/page/creative_island/draw/draw_create.dart b/lib/page/creative_island/draw/draw_create.dart index fe0f1845..87ae7f60 100644 --- a/lib/page/creative_island/draw/draw_create.dart +++ b/lib/page/creative_island/draw/draw_create.dart @@ -14,7 +14,6 @@ import 'package:askaide/page/component/enhanced_textfield.dart'; import 'package:askaide/page/component/global_alert.dart'; import 'package:askaide/page/component/item_selector_search.dart'; import 'package:askaide/page/component/loading.dart'; -import 'package:askaide/page/component/message_box.dart'; import 'package:askaide/page/component/prompt_tags_selector.dart'; import 'package:askaide/page/creative_island/draw/components/content_preview.dart'; import 'package:askaide/page/creative_island/draw/draw_result.dart'; diff --git a/lib/page/creative_island/draw/image_edit_direct.dart b/lib/page/creative_island/draw/image_edit_direct.dart index 1f4db109..7344a3c7 100644 --- a/lib/page/creative_island/draw/image_edit_direct.dart +++ b/lib/page/creative_island/draw/image_edit_direct.dart @@ -9,7 +9,6 @@ import 'package:askaide/page/component/enhanced_button.dart'; import 'package:askaide/page/component/enhanced_textfield.dart'; import 'package:askaide/page/component/global_alert.dart'; import 'package:askaide/page/component/loading.dart'; -import 'package:askaide/page/component/message_box.dart'; import 'package:askaide/page/creative_island/draw/components/content_preview.dart'; import 'package:askaide/page/creative_island/draw/draw_result.dart'; import 'package:askaide/page/component/dialog.dart'; diff --git a/lib/page/lab/draw_board.dart b/lib/page/lab/draw_board.dart index b325dc39..59f4a2b9 100644 --- a/lib/page/lab/draw_board.dart +++ b/lib/page/lab/draw_board.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:askaide/helper/helper.dart'; +import 'package:askaide/helper/logger.dart'; import 'package:askaide/helper/platform.dart'; import 'package:askaide/lang/lang.dart'; import 'package:askaide/page/component/column_block.dart'; @@ -66,15 +67,37 @@ class _DrawboardScreenState extends State { showSuccessMessage('图片保存成功'); } else { - FileSaver.instance - .saveFile( - name: randomId(), - ext: 'png', - bytes: imageData.buffer.asUint8List(), - ) - .then((value) { - showSuccessMessage('文件保存成功'); - }); + if (PlatformTool.isWindows()) { + FileSaver.instance + .saveAs( + name: randomId(), + ext: '.png', + bytes: imageData.buffer.asUint8List(), + mimeType: MimeType.png, + ) + .then((value) async { + if (value == null) { + return ; + } + + await File(value).writeAsBytes(imageData.buffer.asUint8List()); + + Logger.instance.d('文件保存成功: $value'); + showSuccessMessage('文件保存成功'); + }); + } else { + FileSaver.instance + .saveFile( + name: randomId(), + ext: 'png', + bytes: imageData.buffer.asUint8List(), + mimeType: MimeType.png, + ) + .then((value) { + showSuccessMessage('文件保存成功'); + }); + } + } }, icon: const Icon(Icons.save), diff --git a/lib/page/setting/diagnosis.dart b/lib/page/setting/diagnosis.dart index 1d3ece0b..3afbeac7 100644 --- a/lib/page/setting/diagnosis.dart +++ b/lib/page/setting/diagnosis.dart @@ -1,7 +1,10 @@ import 'dart:io'; -import 'package:askaide/helper/env.dart'; +import 'package:askaide/helper/ability.dart'; +import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/logger.dart'; +import 'package:askaide/helper/path.dart'; +import 'package:askaide/helper/platform.dart'; import 'package:askaide/lang/lang.dart'; import 'package:askaide/page/component/background_container.dart'; import 'package:askaide/page/component/column_block.dart'; @@ -13,6 +16,7 @@ import 'package:askaide/repo/settings_repo.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_localization/flutter_localization.dart'; +import 'package:quickalert/quickalert.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; class DiagnosisScreen extends StatefulWidget { @@ -32,12 +36,10 @@ class _DiagnosisScreenState extends State { @override void initState() { super.initState(); - File('$getHomePath/aidea.log').exists().then( + File(PathHelper().getLogfilePath).exists().then( (exist) => { if (exist) - File('${Directory.systemTemp.path}/log.txt') - .readAsString() - .then((value) { + File(PathHelper().getLogfilePath).readAsString().then((value) { setState(() { diagnosisInfo = value; }); @@ -83,26 +85,32 @@ class _DiagnosisScreenState extends State { '该操作将会清空所有设置和数据,是否继续?', () async { final databasePath = - await databaseFactory.getDatabasesPath(); + (await databaseFactory.getDatabasesPath()) + .replaceAll('\\', '/'); Logger.instance.d('databasePath: $databasePath'); - // 删除数据库目录 - await Directory(databasePath).delete( - recursive: true, - ); + try { + // 删除数据库目录 + await Directory(databasePath).delete( + recursive: true, + ); - showSuccessMessage( - // ignore: use_build_context_synchronously - AppLocale.operateSuccess.getString(context), - ); + showSuccessMessage( + // ignore: use_build_context_synchronously + AppLocale.operateSuccess.getString(context), + ); - try { SystemChannels.platform .invokeMethod('SystemNavigator.pop'); } catch (e) { Logger.instance.e(e); - showErrorMessage('应用重启失败,请手动重启'); + // ignore: use_build_context_synchronously + showBeautyDialog( + context, + type: QuickAlertType.error, + text: '数据文件删除失败,请先关闭应用后,手动删除目录 $databasePath 之后再重启应用', + ); } }, danger: true, @@ -153,13 +161,82 @@ class _DiagnosisScreenState extends State { padding: const EdgeInsets.all(10), child: SingleChildScrollView( controller: _controller, - child: ColumnBlock( + child: Column( children: [ - Text( - diagnosisInfo, - style: const TextStyle( - fontSize: 10, - ), + ColumnBlock( + innerPanding: 5, + padding: const EdgeInsets.all(10), + children: [ + Text( + '服务器: ${APIServer().url}', + style: const TextStyle( + fontSize: 10, + ), + ), + Text( + '当前用户 ID: ${APIServer().localUserID()}', + style: const TextStyle( + fontSize: 10, + ), + ), + const Text( + '客户端版本: $clientVersion', + style: TextStyle( + fontSize: 10, + ), + ), + Text( + '操作系统: ${PlatformTool.operatingSystem()} | ${PlatformTool.operatingSystemVersion()}', + style: const TextStyle( + fontSize: 10, + ), + ), + Text( + 'OpenAI 自定义: ${Ability().enableLocalOpenAI}', + style: const TextStyle( + fontSize: 10, + ), + ), + FutureBuilder( + future: databaseFactory.getDatabasesPath(), + builder: (context, snapshot) { + return Text( + '本地数据库: ${snapshot.data?.replaceAll('\\', '/')}', + style: const TextStyle( + fontSize: 10, + ), + ); + }, + ), + Text( + '日志文件: ${PathHelper().getLogfilePath}', + style: const TextStyle( + fontSize: 10, + ), + ), + Text( + '缓存目录: ${PathHelper().getCachePath}', + style: const TextStyle( + fontSize: 10, + ), + ), + Text( + '主目录: ${PathHelper().getHomePath}', + style: const TextStyle( + fontSize: 10, + ), + ), + ], + ), + ColumnBlock( + children: [ + Text( + diagnosisInfo, + style: const TextStyle( + fontSize: 10, + ), + ), + ], ), ], ), diff --git a/lib/page/setting/setting_screen.dart b/lib/page/setting/setting_screen.dart index 56a98016..5b0b450e 100644 --- a/lib/page/setting/setting_screen.dart +++ b/lib/page/setting/setting_screen.dart @@ -171,21 +171,6 @@ class _SettingScreenState extends State { }, ), - // 诊断 - if (PlatformTool.isMacOS() || - PlatformTool.isLinux() || - PlatformTool.isWindows()) - SettingsTile( - title: Text(AppLocale.diagnostic.getString(context)), - trailing: Icon( - CupertinoIcons.chevron_forward, - size: MediaQuery.of(context).textScaleFactor * 18, - color: Colors.grey, - ), - onPressed: (context) { - context.push('/diagnosis'); - }, - ), // 检查更新 if (!PlatformTool.isIOS()) SettingsTile( @@ -255,11 +240,33 @@ class _SettingScreenState extends State { color: Colors.grey, ), onPressed: (_) { + var tapCount = 0; showAboutDialog( context: context, applicationName: 'AIdea', - applicationIcon: - Image.asset('assets/app.png', width: 40), + applicationIcon: GestureDetector( + onTap: () { + if (userHasLabPermission(state)) { + return; + } + + tapCount++; + + if (tapCount > 5) { + tapCount = 0; + + final showLab = forceShowLab(); + widget.settings.set(settingForceShowLab, + showLab ? 'false' : 'true'); + + showSuccessMessage( + showLab ? '已关闭实验室功能' : '已启用实验室功能'); + + setState(() {}); + } + }, + child: Image.asset('assets/app.png', width: 40), + ), applicationVersion: clientVersion, children: [ Text(AppLocale.aIdeaApp.getString(context)), @@ -270,50 +277,49 @@ class _SettingScreenState extends State { ], ), - if (state is AccountLoaded && - state.error == null && - state.user != null && - state.user!.control.withLab) + if (userHasLabPermission(state) || forceShowLab()) SettingsSection( title: const Text('实验室'), tiles: [ - SettingsTile( - title: const Text('模型 Gallery'), - trailing: Icon( - CupertinoIcons.chevron_forward, - size: MediaQuery.of(context).textScaleFactor * 18, - color: Colors.grey, + if (userHasLabPermission(state)) + SettingsTile( + title: const Text('模型 Gallery'), + trailing: Icon( + CupertinoIcons.chevron_forward, + size: MediaQuery.of(context).textScaleFactor * 18, + color: Colors.grey, + ), + onPressed: (context) { + context.push('/creative-island/models'); + }, ), - onPressed: (context) { - context.push('/creative-island/models'); - }, - ), + if (userHasLabPermission(state)) + SettingsTile( + title: const Text('画板'), + trailing: Icon( + CupertinoIcons.chevron_forward, + size: MediaQuery.of(context).textScaleFactor * 18, + color: Colors.grey, + ), + onPressed: (context) { + context.push('/lab/draw-board'); + }, + ), + + // 自定义服务器 + _buildServerSelfHostedSetting(customColors), + // 诊断 SettingsTile( - title: const Text('画板'), + title: Text(AppLocale.diagnostic.getString(context)), trailing: Icon( CupertinoIcons.chevron_forward, size: MediaQuery.of(context).textScaleFactor * 18, color: Colors.grey, ), onPressed: (context) { - context.push('/lab/draw-board'); + context.push('/diagnosis'); }, ), - - // SettingsTile( - // title: const Text('用户中心'), - // trailing: Icon( - // CupertinoIcons.chevron_forward, - // size: MediaQuery.of(context).textScaleFactor * 18, - // color: Colors.grey, - // ), - // onPressed: (context) { - // context.push('/lab/user-center'); - // }, - // ), - - // 自定义服务器 - _buildServerSelfHostedSetting(customColors), ], ), // 社交媒体图标 @@ -326,6 +332,19 @@ class _SettingScreenState extends State { ); } + /// 用户是否有实验室访问权限 + bool userHasLabPermission(AccountState state) { + return state is AccountLoaded && + state.error == null && + state.user != null && + state.user!.control.withLab; + } + + /// 是否强制显示实验室功能 + bool forceShowLab() { + return widget.settings.boolDefault(settingForceShowLab, false); + } + CustomSettingsSection _buildAccountQuotaCard( BuildContext context, AccountState state, diff --git a/lib/repo/api/creative.dart b/lib/repo/api/creative.dart index 2f45560c..7d7ec84a 100644 --- a/lib/repo/api/creative.dart +++ b/lib/repo/api/creative.dart @@ -156,6 +156,8 @@ class CreativeIslandCapacity { bool showImageStrength; List filters; List artisticStyles; + List artisticTextStyles; + List artisticTextFonts; CreativeIslandCapacity({ required this.showAIRewrite, @@ -171,6 +173,8 @@ class CreativeIslandCapacity { this.showImageStrength = false, this.filters = const [], this.artisticStyles = const [], + this.artisticTextStyles = const [], + this.artisticTextFonts = const [], }); toJson() => { @@ -187,6 +191,10 @@ class CreativeIslandCapacity { 'show_image_strength': showImageStrength, 'filters': filters.map((e) => e.toJson()).toList(), 'artistic_styles': artisticStyles.map((e) => e.toJson()).toList(), + 'artistic_text_styles': + artisticTextStyles.map((e) => e.toJson()).toList(), + 'artistic_text_fonts': + artisticTextFonts.map((e) => e.toJson()).toList(), }; static CreativeIslandCapacity fromJson(Map json) { @@ -214,6 +222,13 @@ class CreativeIslandCapacity { artisticStyles: ((json['artistic_styles'] ?? []) as List) .map((e) => CreativeIslandArtisticStyle.fromJson(e)) .toList(), + artisticTextStyles: + ((json['artistic_text_styles'] ?? []) as List) + .map((e) => CreativeIslandArtisticStyle.fromJson(e)) + .toList(), + artisticTextFonts: ((json['artistic_text_fonts'] ?? []) as List) + .map((e) => CreativeIslandArtisticStyle.fromJson(e)) + .toList(), ); } } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 8d267c74..13a0619f 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -15,7 +15,7 @@ import media_kit_libs_macos_video import media_kit_video import package_info_plus import path_provider_foundation -import record_macos +import record_darwin import screen_brightness_macos import share_plus import shared_preferences_foundation @@ -35,7 +35,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) - RecordMacosPlugin.register(with: registry.registrar(forPlugin: "RecordMacosPlugin")) + RecordPlugin.register(with: registry.registrar(forPlugin: "RecordPlugin")) ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index f946cc5d..c2bf8938 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -27,7 +27,8 @@ PODS: - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - record_macos (0.2.0): + - record_darwin (1.0.0): + - Flutter - FlutterMacOS - screen_brightness_macos (0.1.0): - FlutterMacOS @@ -59,7 +60,7 @@ DEPENDENCIES: - media_kit_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - - record_macos (from `Flutter/ephemeral/.symlinks/plugins/record_macos/macos`) + - record_darwin (from `Flutter/ephemeral/.symlinks/plugins/record_darwin/macos`) - screen_brightness_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) @@ -97,8 +98,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos path_provider_foundation: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin - record_macos: - :path: Flutter/ephemeral/.symlinks/plugins/record_macos/macos + record_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/record_darwin/macos screen_brightness_macos: :path: Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos share_plus: @@ -122,18 +123,18 @@ SPEC CHECKSUMS: flutter_tts: 64651204e5d276ffea5a910f942d5e9785a96085 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a - in_app_purchase_storekit: 4fb7ee9e824b1f09107fbfbbce8c4b276366dc43 + in_app_purchase_storekit: 9e9931234f0adcf71ae323f8c83785b96030edf1 media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82 media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5 media_kit_video: c75b07f14d59706c775778e4dd47dd027de8d1e5 package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 - record_macos: 937889e0f2a7a12b6fc14e97a3678e5a18943de6 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + record_darwin: 1f6619f2abac4d1ca91d3eeab038c980d76f1517 screen_brightness_macos: 2d6d3af2165592d9a55ffcd95b7550970e41ebda share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7 - shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 sign_in_with_apple: a9e97e744e8edc36aefc2723111f652102a7a727 - sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea + sqflite: d0307f984e859ce2bd39b230d672a448ea3f47b4 url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 diff --git a/pubspec.lock b/pubspec.lock index 978822b3..0327db3d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "64.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.2.0" animated_button_bar: dependency: "direct main" description: @@ -41,14 +41,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.8" + ansicolor: + dependency: transitive + description: + name: ansicolor + sha256: "8bf17a8ff6ea17499e40a2d2542c2f481cd7615760c6d34065cb22bfd22e6880" + url: "https://pub.dev" + source: hosted + version: "2.0.2" archive: dependency: transitive description: name: archive - sha256: "06a96f1249f38a00435b3b0c9a3246d934d7dbc8183fc7c9e56989860edb99d4" + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" url: "https://pub.dev" source: hosted - version: "3.4.4" + version: "3.4.10" args: dependency: transitive description: @@ -69,18 +77,18 @@ packages: dependency: "direct main" description: name: audioplayers - sha256: d9f6ca8e9b3e5af5e73d4c814404566f72698ee7ba35487bdf2baa6749e7503f + sha256: c05c6147124cd63e725e861335a8b4d57300b80e6e92cea7c145c739223bbaef url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.2.1" audioplayers_android: dependency: transitive description: name: audioplayers_android - sha256: fb01b9481f431fe04ac60f1f97ce8158383f2dc754558820592f795d81ca9d53 + sha256: b00e1a0e11365d88576320ec2d8c192bc21f1afb6c0e5995d1c57ae63156acb5 url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.0.3" audioplayers_darwin: dependency: transitive description: @@ -174,26 +182,26 @@ packages: dependency: transitive description: name: build_daemon - sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.1" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: "64e12b0521812d1684b1917bc80945625391cb9bdd4312536b1d69dcb6133ed8" + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" + sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" url: "https://pub.dev" source: hosted - version: "2.4.6" + version: "2.4.8" build_runner_core: dependency: transitive description: @@ -214,34 +222,34 @@ packages: dependency: transitive description: name: built_value - sha256: a8de5955205b4d1dbbbc267daddf2178bd737e4bab8987c04a500478c9651e74 + sha256: a3ec2e0f967bc47f69f95009bb93db936288d61d5343b9436e378b28a2f830c6 url: "https://pub.dev" source: hosted - version: "8.6.3" + version: "8.9.0" cached_network_image: dependency: "direct main" description: name: cached_network_image - sha256: f98972704692ba679db144261172a8e20feb145636c617af0eb4022132a6797f + sha256: "28ea9690a8207179c319965c13cd8df184d5ee721ae2ce60f398ced1219cea1f" url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" cached_network_image_platform_interface: dependency: transitive description: name: cached_network_image_platform_interface - sha256: "56aa42a7a01e3c9db8456d9f3f999931f1e05535b5a424271e9a38cabf066613" + sha256: "9e90e78ae72caa874a323d78fa6301b3fb8fa7ea76a8f96dc5b5bf79f283bf2f" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" cached_network_image_web: dependency: transitive description: name: cached_network_image_web - sha256: "759b9a9f8f6ccbb66c185df805fac107f05730b1dab9c64626d1008cca532257" + sha256: "42a835caa27c220d1294311ac409a43361088625a4f23c820b006dd9bffb3316" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" characters: dependency: transitive description: @@ -250,14 +258,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" - charcode: - dependency: transitive - description: - name: charcode - sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 - url: "https://pub.dev" - source: hosted - version: "1.3.1" checked_yaml: dependency: transitive description: @@ -302,10 +302,10 @@ packages: dependency: transitive description: name: code_builder - sha256: "1be9be30396d7e4c0db42c35ea6ccd7cc6a1e19916b5dc64d6ac216b5544d677" + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.10.0" collection: dependency: transitive description: @@ -314,30 +314,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" - convert: + console: dependency: transitive description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + name: console + sha256: e04e7824384c5b39389acdd6dc7d33f3efe6b232f6f16d7626f194f6a01ad69a url: "https://pub.dev" source: hosted - version: "3.1.1" - coverage: + version: "4.1.0" + convert: dependency: transitive description: - name: coverage - sha256: "595a29b55ce82d53398e1bcc2cba525d7bd7c59faeb2d2540e9d42c390cfeeeb" + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" url: "https://pub.dev" source: hosted - version: "1.6.4" + version: "3.1.1" cross_file: dependency: transitive description: name: cross_file - sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb + sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" url: "https://pub.dev" source: hosted - version: "0.3.3+5" + version: "0.3.3+7" crypto: dependency: "direct main" description: @@ -366,10 +366,10 @@ packages: dependency: "direct main" description: name: custom_sliding_segmented_control - sha256: a12d1908bb3fe06aabd4becd7def608cdd77b01b7a9f79e37d9414b478523a34 + sha256: "05b73fa48d57218bfdf806bad68a859812b216cd81fe81c6cbefde89f39eb257" url: "https://pub.dev" source: hosted - version: "1.7.5" + version: "1.8.1" dart_openai: dependency: "direct main" description: @@ -383,26 +383,26 @@ packages: dependency: transitive description: name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.4" dbus: dependency: transitive description: name: dbus - sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "0.7.8" - dev_test: + version: "0.7.10" + dev_build: dependency: transitive description: - name: dev_test - sha256: "0d49b920844062a518edb79fc1dbf9ff6d9bf3c9ab600e3847b7502c27c0caab" + name: dev_build + sha256: e476ac99174842cdb01e64c1d379d041d2150f9ad2cdd2713eb1ca1bdbf30507 url: "https://pub.dev" source: hosted - version: "0.16.1+4" + version: "0.16.3+2" dio: dependency: "direct main" description: @@ -431,10 +431,10 @@ packages: dependency: transitive description: name: extended_list - sha256: "7eb3c21cd8b7710b0092cb0606807cd24614e5832e65f370e5dee226d317de44" + sha256: b27a2f0f55dadbf5b273bdaaf9307a7e0098a9fc0c4b8eb60ae98c319af596bc url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.1" extended_list_library: dependency: transitive description: @@ -479,10 +479,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" file_picker: dependency: "direct main" description: @@ -494,11 +494,12 @@ packages: file_saver: dependency: "direct main" description: - name: file_saver - sha256: "591d25e750e3a4b654f7b0293abc2ed857242f82ca7334051b2a8ceeb369dac8" - url: "https://pub.dev" - source: hosted - version: "0.2.8" + path: "." + ref: main + resolved-ref: "0cc9684271f69d01dfaf63a03e29415b8246b984" + url: "https://github.com/incrediblezayed/file_saver" + source: git + version: "0.2.9" fixnum: dependency: transitive description: @@ -613,10 +614,10 @@ packages: dependency: "direct main" description: name: flutter_local_notifications - sha256: "53c332ecee8e4d723269c1c2d0cdf7cbbff0a66cc0554d230a6f38cae81760d1" + sha256: "5f79a1be5e9fef9ddd7f494532d31851399099f9defc21ebcb1ae4539e8a37f1" url: "https://pub.dev" source: hosted - version: "14.1.4" + version: "14.1.5" flutter_local_notifications_linux: dependency: transitive description: @@ -650,10 +651,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "8afc9a6aa6d8e8063523192ba837149dbf3d377a37c0b0fc579149a1fbd4a619" + sha256: "30088ce826b5b9cfbf9e8bece34c716c8a59fa54461dcae1e4ac01a94639e762" url: "https://pub.dev" source: hosted - version: "0.6.18" + version: "0.6.18+3" flutter_math_fork: dependency: "direct main" description: @@ -666,18 +667,18 @@ packages: dependency: "direct main" description: name: flutter_native_splash - sha256: "91004565166dbbc7a85e7e99b84124a287839830ca957cfe45004793fe6fe69f" + sha256: "17d9671396fb8ec45ad10f4a975eb8a0f70bedf0fdaf0720b31ea9de6da8c4da" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.3.7" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c + sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da url: "https://pub.dev" source: hosted - version: "2.0.16" + version: "2.0.17" flutter_slidable: dependency: "direct main" description: @@ -698,10 +699,10 @@ packages: dependency: transitive description: name: flutter_svg - sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338" + sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.9" flutter_test: dependency: "direct dev" description: flutter @@ -711,10 +712,10 @@ packages: dependency: "direct main" description: name: flutter_tts - sha256: "23d47e1335c632228b80d9693e2494a834393fff5893b66e8ae494dcce4e9867" + sha256: cbb3fd43b946e62398560235469e6113e4fe26c40eab1b7cb5e7c417503fb3a8 url: "https://pub.dev" source: hosted - version: "3.8.3" + version: "3.8.5" flutter_web_plugins: dependency: transitive description: flutter @@ -732,10 +733,10 @@ packages: dependency: transitive description: name: font_awesome_flutter - sha256: "5fb789145cae1f4c3245c58b3f8fb287d055c26323879eab57a7bf0cfd1e45f3" + sha256: "52671aea66da73b58d42ec6d0912b727a42248dd9a7c76d6c20f275783c48c08" url: "https://pub.dev" source: hosted - version: "10.5.0" + version: "10.6.0" frontend_server_client: dependency: transitive description: @@ -744,6 +745,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.0" + get_it: + dependency: transitive + description: + name: get_it + sha256: e6017ce7fdeaf218dc51a100344d8cb70134b80e28b760f8bb23c242437bafd7 + url: "https://pub.dev" + source: hosted + version: "7.6.7" glob: dependency: transitive description: @@ -812,10 +821,10 @@ packages: dependency: "direct main" description: name: image - sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271" + sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d" url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "4.1.4" image_gallery_saver: dependency: "direct main" description: @@ -828,34 +837,34 @@ packages: dependency: "direct main" description: name: in_app_purchase - sha256: "17074a826f32e36f6cc36effcbcf92abc3b0d8a1e02f42583eaa4c6c79d4f026" + sha256: def70fbaa2a274f4d835677459f6f7afc5469de912438f86076e51cbd4cbd5b4 url: "https://pub.dev" source: hosted - version: "3.1.10" + version: "3.1.13" in_app_purchase_android: dependency: transitive description: name: in_app_purchase_android - sha256: "63997b855f10799a1022939bbf02e3f59b6f400f4deee858f46fd528df5f5fab" + sha256: "28164faac635a6cc357c96f47813e675eec7622a8f41e829b501573dbbce2cce" url: "https://pub.dev" source: hosted - version: "0.3.0+13" + version: "0.3.0+17" in_app_purchase_platform_interface: dependency: transitive description: name: in_app_purchase_platform_interface - sha256: "463b980dd4605868534fd8e57cd7b57ca042c0dee98ed21df99196be59eb8741" + sha256: "412efce2b9238c5ace4f057acad43f793ed06880e366d26ae322e796cadb051a" url: "https://pub.dev" source: hosted - version: "1.3.5" + version: "1.3.7" in_app_purchase_storekit: dependency: transitive description: name: in_app_purchase_storekit - sha256: "88afd256c7605d431f0ce29d0161f9554851f90ecb92ceb9e18196c4e7858d52" + sha256: c4b17a7f2ca8ddc7fd7996a8c32a3af6beddf91d651997c8675a5f23c103c9bc url: "https://pub.dev" source: hosted - version: "0.3.6+7" + version: "0.3.8+1" intl: dependency: "direct main" description: @@ -949,10 +958,10 @@ packages: description: path: "." ref: HEAD - resolved-ref: "2ec522a429bd883a6493220efc710b8491a66438" + resolved-ref: bdc79b585ce6e07212be111569b6151d7142b577 url: "https://github.com/Bungeefan/logger.git" source: git - version: "2.0.2" + version: "2.0.2+1" logging: dependency: transitive description: @@ -965,18 +974,18 @@ packages: dependency: "direct main" description: name: markdown - sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd + sha256: "1b134d9f8ff2da15cb298efe6cd8b7d2a78958c1b00384ebcbdf13fe340a6c90" url: "https://pub.dev" source: hosted - version: "7.1.1" + version: "7.2.1" markdown_widget: dependency: "direct main" description: name: markdown_widget - sha256: b69334a1dd633c32d688735d771ebaf5490f713cd00917cb52b53c14c2c09d81 + sha256: "4ac442aa4debbcf16c4030e1313167f18e0fa29f4d7b6f2ff23405d6d7689f6f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2+3" matcher: dependency: transitive description: @@ -1081,6 +1090,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + msix: + dependency: "direct dev" + description: + name: msix + sha256: "68679afc7d7117467250363dea4fb62db7520a23a9490bf4b65794655235a1d5" + url: "https://pub.dev" + source: hosted + version: "3.9.1" nested: dependency: transitive description: @@ -1089,14 +1106,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" - node_preamble: - dependency: transitive - description: - name: node_preamble - sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" - url: "https://pub.dev" - source: hosted - version: "2.0.2" octo_image: dependency: transitive description: @@ -1117,10 +1126,10 @@ packages: dependency: transitive description: name: package_info_plus - sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" + sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" url: "https://pub.dev" source: hosted - version: "5.0.1" + version: "4.2.0" package_info_plus_platform_interface: dependency: transitive description: @@ -1130,7 +1139,7 @@ packages: source: hosted version: "2.0.1" path: - dependency: transitive + dependency: "direct main" description: name: path sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" @@ -1149,26 +1158,26 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.2" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -1181,10 +1190,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -1213,26 +1222,26 @@ packages: dependency: transitive description: name: platform - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.8" pointycastle: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" pool: dependency: transitive description: @@ -1245,18 +1254,18 @@ packages: dependency: transitive description: name: process_run - sha256: ceacfac6d566a36c895d64edc7e429efb2d6b6303b5e28d5c13bc59fe6e8974e + sha256: cad2c57a34f8313a4182e34e31e0b2f12972eef3d0930cdc7ab3240bb8cad380 url: "https://pub.dev" source: hosted - version: "0.13.1" + version: "0.14.1+3" provider: dependency: "direct main" description: name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" url: "https://pub.dev" source: hosted - version: "6.0.5" + version: "6.1.1" pub_semver: dependency: transitive description: @@ -1318,50 +1327,58 @@ packages: dependency: "direct main" description: name: record - sha256: f703397f5a60d9b2b655b3acc94ba079b2d9a67dc0725bdb90ef2fee2441ebf7 + sha256: "5c8e12c692a4800b33f5f8b6c821ea083b12bfdbd031b36ba9322c40a4eeecc9" url: "https://pub.dev" source: hosted - version: "4.4.4" - record_linux: + version: "5.0.4" + record_android: dependency: transitive description: - name: record_linux - sha256: "348db92c4ec1b67b1b85d791381c8c99d7c6908de141e7c9edc20dad399b15ce" + name: record_android + sha256: "805ecaa232a671aff2ee9ec4730ef6addb97c548d2db6b1fbd5197f1d4f47a5a" url: "https://pub.dev" source: hosted - version: "0.4.1" - record_macos: + version: "1.0.4" + record_darwin: + dependency: transitive + description: + name: record_darwin + sha256: ee8cb1bb1712d7ce38140ecabe70e5c286c02f05296d66043bee865ace7eb1b9 + url: "https://pub.dev" + source: hosted + version: "1.0.1" + record_linux: dependency: transitive description: - name: record_macos - sha256: d1d0199d1395f05e218207e8cacd03eb9dc9e256ddfe2cfcbbb90e8edea06057 + name: record_linux + sha256: "7d0e70cd51635128fe9d37d89bafd6011d7cbba9af8dc323079ae60f23546aef" url: "https://pub.dev" source: hosted - version: "0.2.2" + version: "0.7.1" record_platform_interface: dependency: transitive description: name: record_platform_interface - sha256: "7a2d4ce7ac3752505157e416e4e0d666a54b1d5d8601701b7e7e5e30bec181b4" + sha256: "3a4b56e94ecd2a0b2b43eb1fa6f94c5b8484334f5d38ef43959c4bf97fb374cf" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "1.0.2" record_web: dependency: transitive description: name: record_web - sha256: "219ffb4ca59b4338117857db56d3ffadbde3169bcaf1136f5f4d4656f4a2372d" + sha256: "24847cdbcf999f7a5762170792f622ac844858766becd0f2370ec8ae22f7526e" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "1.0.5" record_windows: dependency: transitive description: name: record_windows - sha256: "42d545155a26b20d74f5107648dbb3382dbbc84dc3f1adc767040359e57a1345" + sha256: "39998b3ea7d8d28b04159d82220e6e5e32a7c357c6fb2794f5736beea272f6c3" url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "1.0.2" rxdart: dependency: transitive description: @@ -1462,10 +1479,10 @@ packages: dependency: transitive description: name: shared_preferences - sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_android: dependency: transitive description: @@ -1478,26 +1495,26 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.5" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shared_preferences_web: dependency: transitive description: @@ -1510,10 +1527,10 @@ packages: dependency: transitive description: name: shared_preferences_windows - sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shelf: dependency: transitive description: @@ -1522,22 +1539,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" - shelf_packages_handler: - dependency: transitive - description: - name: shelf_packages_handler - sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - shelf_static: - dependency: transitive - description: - name: shelf_static - sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e - url: "https://pub.dev" - source: hosted - version: "1.1.2" shelf_web_socket: dependency: transitive description: @@ -1603,10 +1604,10 @@ packages: dependency: transitive description: name: source_gen - sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.5.0" source_helper: dependency: transitive description: @@ -1615,22 +1616,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.4" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - source_maps: - dependency: transitive - description: - name: source_maps - sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" - url: "https://pub.dev" - source: hosted - version: "0.10.12" source_span: dependency: transitive description: @@ -1643,34 +1628,34 @@ packages: dependency: "direct main" description: name: sqflite - sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" + sha256: c2c32eb0c74021d987336522acc3b6bf0082fbd0c540c36a9cf4ddb8ba891ddc url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a" + sha256: "76db4d324c8cbb16ca5b60ad2f3d25cec953107c93ae65aafa480d3e6fb69f14" url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.5.2-1" sqflite_common_ffi: dependency: "direct main" description: name: sqflite_common_ffi - sha256: "0d5cc1be2eb18400ac6701c31211d44164393aa75886093002ecdd947be04f93" + sha256: "35d2fce1e971707c227cc4775cc017d5eafe06c2654c3435ebd5c3ad6c170f5f" url: "https://pub.dev" source: hosted - version: "2.3.0+2" + version: "2.3.0+4" sqflite_common_ffi_web: dependency: "direct main" description: name: sqflite_common_ffi_web - sha256: db9a7ef6adcfb6c9b4115f628c1d3efe3774b385309a80e75c1bafb97da2c9d1 + sha256: "355494e4b189e44cc0fc60f6adeece798641d1809ec0d070959cdc6033fbddab" url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.4.2+1" sqlite3: dependency: transitive description: @@ -1715,10 +1700,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.0+1" term_glyph: dependency: transitive description: @@ -1727,14 +1712,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" - test: - dependency: transitive - description: - name: test - sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f - url: "https://pub.dev" - source: hosted - version: "1.24.9" test_api: dependency: transitive description: @@ -1743,14 +1720,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.1" - test_core: - dependency: transitive - description: - name: test_core - sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a - url: "https://pub.dev" - source: hosted - version: "0.5.9" tiktoken: dependency: "direct main" description: @@ -1827,66 +1796,66 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" + sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c url: "https://pub.dev" source: hosted - version: "6.1.14" + version: "6.2.4" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 + sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.2.2" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f" + sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" url: "https://pub.dev" source: hosted - version: "6.1.5" + version: "6.2.4" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e + sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.1.1" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88 + sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234 url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "3.1.0" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" + sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.3.1" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "2942294a500b4fa0b918685aff406773ba0a4cd34b7f42198742a94083020ce5" + sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2" url: "https://pub.dev" source: hosted - version: "2.0.20" + version: "2.2.0" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069" + sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.1.1" uuid: dependency: "direct main" description: @@ -1907,26 +1876,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f" + sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+2" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f" + sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+2" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e" + sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+2" vector_math: dependency: transitive description: @@ -1943,14 +1912,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.0+2" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 - url: "https://pub.dev" - source: hosted - version: "11.10.0" volume_controller: dependency: transitive description: @@ -1987,10 +1948,10 @@ packages: dependency: transitive description: name: waterfall_flow - sha256: "84486ac34f51977176990ada50b44d83be24726814fa03c22c1e10e3791cc3f2" + sha256: "11538b0d890458e55e6248b177732495d20893cfc7e85d7e8dbf4fdce61c9f10" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" web: dependency: transitive description: @@ -2007,14 +1968,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.0" - webkit_inspection_protocol: - dependency: transitive - description: - name: webkit_inspection_protocol - sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" - url: "https://pub.dev" - source: hosted - version: "1.2.1" widgets_to_image: dependency: "direct main" description: @@ -2035,10 +1988,10 @@ packages: dependency: transitive description: name: xdg_directories - sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" xml: dependency: transitive description: @@ -2056,5 +2009,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.2.0 <4.0.0" + dart: ">=3.2.0-194.0.dev <4.0.0" flutter: ">=3.13.0" diff --git a/pubspec.yaml b/pubspec.yaml index 49f7e4f3..75661ca5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. # 应用正式发布时,需要同步修改 lib/helper/constant.dart 中的 VERSION 值 -version: 1.0.11+1 +version: 1.0.12+1 environment: sdk: '>=3.0.0 <4.0.0' @@ -66,7 +66,10 @@ dependencies: isolate_image_compress: ^2.0.0 image: ^4.0.15 flutter_cache_manager: ^3.3.0 - file_saver: ^0.2.1 + file_saver: + git: + url: https://github.com/incrediblezayed/file_saver + ref: main image_gallery_saver: ^1.7.1 tiktoken: ^1.0.3 flutter_colorpicker: ^1.0.3 @@ -78,7 +81,7 @@ dependencies: dio_smart_retry: ^1.4.0 qiniu_flutter_sdk: ^0.4.0 sign_in_with_apple: ^4.3.0 - record: ^4.4.4 + record: ^5.0.4 animations: ^2.0.7 animated_text_kit: ^4.2.2 flutter_localization: ^0.1.11 @@ -121,6 +124,7 @@ dependencies: media_kit: ^1.1.10 media_kit_video: ^1.2.4 media_kit_libs_video: ^1.0.4 + path: ^1.8.3 dev_dependencies: flutter_test: @@ -134,6 +138,7 @@ dev_dependencies: flutter_lints: ^2.0.0 flutter_launcher_icons: "^0.12.0" build_runner: ^2.3.3 + msix: ^3.9.1 flutter_icons: image_path: "assets/app.png" @@ -214,4 +219,11 @@ flutter_native_splash: android_disable_fullscreen: true tobias: - url_scheme: alipay2021004101661425 \ No newline at end of file + url_scheme: alipay2021004101661425 + +msix_config: + display_name: AIdea + publisher_display_name: Shenzhen Gulu Artificial Intelligence Technology Co., Ltd. + identity_name: cc.aicode.flutter.askaide.askaide + logo_path: assets/app.png + execution_alias: AIdea diff --git a/windows/.gitignore b/windows/.gitignore index d492d0d9..0ffe48bb 100644 --- a/windows/.gitignore +++ b/windows/.gitignore @@ -15,3 +15,6 @@ x86/ *.[Cc]ache # but keep track of directories ending in .cache !*.[Cc]ache/ + +.vs/ +out/ \ No newline at end of file diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index 2d2f4aa5..fd1a21e8 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -99,3 +99,8 @@ install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" CONFIGURATIONS Profile;Release COMPONENT Runtime) + +# Install sqlite3.dll +install(FILES "sqlite3.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index a0ecc1c2..d85164e5 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(400, 800); - if (!window.Create(L"askaide", origin, size)) { + if (!window.Create(L"AIdea", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true);