From 8a74afe5120158db26a5823c94444c4b95de1139 Mon Sep 17 00:00:00 2001 From: joyhope Date: Sat, 2 Dec 2023 09:48:12 +0800 Subject: [PATCH 1/8] support linux --- lib/helper/platform.dart | 8 ++++++++ lib/main.dart | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/helper/platform.dart b/lib/helper/platform.dart index e48aea33..d4bd52b1 100644 --- a/lib/helper/platform.dart +++ b/lib/helper/platform.dart @@ -39,6 +39,14 @@ class PlatformTool { } } + static bool isLinux() { + try { + return Platform.isLinux; + } catch (e) { + return false; + } + } + static String operatingSystem() { try { return Platform.operatingSystem; diff --git a/lib/main.dart b/lib/main.dart index bd319ab6..5e7b2012 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -118,7 +118,7 @@ void main() async { if (kIsWeb) { databaseFactory = databaseFactoryFfiWeb; } else { - if (PlatformTool.isWindows()) { + if (PlatformTool.isWindows() || PlatformTool.isLinux()) { sqfliteFfiInit(); databaseFactory = databaseFactoryFfi; } From 2a7cd8746744aaa311d72792d4091e62f460f315 Mon Sep 17 00:00:00 2001 From: joyhope Date: Sun, 3 Dec 2023 21:00:32 +0800 Subject: [PATCH 2/8] pass android build --- android/app/build.gradle | 2 +- android/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 92196c97..cf7674b5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -32,7 +32,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion flutter.compileSdkVersion + compileSdkVersion 34 ndkVersion flutter.ndkVersion compileOptions { diff --git a/android/build.gradle b/android/build.gradle index 713d7f6e..07f90508 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.20' repositories { google() mavenCentral() From 39cd595aec5a7477aa4bcdec9e9c4204b8e3a91d Mon Sep 17 00:00:00 2001 From: mylxsw Date: Mon, 4 Dec 2023 11:22:43 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E6=9C=AA=E7=99=BB=E5=BD=95=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=9C=A8,=E5=8F=AF=E4=BB=A5=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E6=9B=B4=E5=A4=9A=E5=86=85=E5=AE=B9,=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bloc/free_count_bloc.dart | 2 +- lib/page/balance/free_statistics.dart | 12 ++++++++++- lib/page/component/chat/chat_preview.dart | 4 +--- lib/page/component/chat/voice_record.dart | 10 ++++++---- lib/page/component/dialog.dart | 12 ++++++++++- lib/page/creative_island/draw/draw_list.dart | 20 ++++++++----------- .../creative_island/gallery/gallery_item.dart | 20 ++++++++----------- lib/page/setting/setting_screen.dart | 4 +++- lib/repo/api_server.dart | 17 +++++++++++++++- 9 files changed, 65 insertions(+), 36 deletions(-) diff --git a/lib/bloc/free_count_bloc.dart b/lib/bloc/free_count_bloc.dart index 3b45df5c..d22d49a5 100644 --- a/lib/bloc/free_count_bloc.dart +++ b/lib/bloc/free_count_bloc.dart @@ -15,7 +15,7 @@ class FreeCountBloc extends Bloc { on((event, emit) async { if (!Ability().enableAPIServer()) { emit(FreeCountLoadedState( - counts: counts, + counts: await APIServer().freeChatCounts(), needSignin: event.checkSigninStatus, )); return; diff --git a/lib/page/balance/free_statistics.dart b/lib/page/balance/free_statistics.dart index 9021c982..5c41309c 100644 --- a/lib/page/balance/free_statistics.dart +++ b/lib/page/balance/free_statistics.dart @@ -65,7 +65,17 @@ class _FreeStatisticsPageState extends State { listener: (BuildContext context, FreeCountState state) { if (state is FreeCountLoadedState) { if (state.needSignin) { - context.go('/login'); + showBeautyDialog( + context, + type: QuickAlertType.warning, + text: '免费模型需登录账号后使用', + confirmBtnText: '去登录', + onConfirmBtnTap: () { + context.pop(); + context.go('/login'); + }, + showCancelBtn: true, + ); } } }, diff --git a/lib/page/component/chat/chat_preview.dart b/lib/page/component/chat/chat_preview.dart index 8f0085d3..4d256523 100644 --- a/lib/page/component/chat/chat_preview.dart +++ b/lib/page/component/chat/chat_preview.dart @@ -488,9 +488,7 @@ class _ChatPreviewState extends State { if (extra['error'] != null && extra['error'] != '') { var e1 = extra['error']; try { - if (e1 is LanguageText) { - e1 = (e1 as String).getString(context); - } + e1 = (e1 as String).getString(context); // ignore: empty_catches } catch (ignored) {} confirmMessage = e1; diff --git a/lib/page/component/chat/voice_record.dart b/lib/page/component/chat/voice_record.dart index 12c38807..b13e8ed0 100644 --- a/lib/page/component/chat/voice_record.dart +++ b/lib/page/component/chat/voice_record.dart @@ -136,9 +136,11 @@ class _VoiceRecordState extends State { backgroundColor: _voiceRecording ? customColors.linkColor : customColors.linkColor!.withAlpha(200), - child: _voiceRecording - ? const Icon(Icons.mic, size: 50) - : const Icon(Icons.mic, size: 50), + child: const Icon( + Icons.mic, + size: 50, + color: Colors.white, + ), ), ), ), @@ -162,7 +164,7 @@ class _VoiceRecordState extends State { } final voiceDuration = DateTime.now().difference(_voiceStartTime!).inSeconds; - if (voiceDuration < 2) { + if (voiceDuration < 1) { showErrorMessage('说话时间太短'); _voiceStartTime = null; File.fromUri(Uri.parse(resPath)).delete(); diff --git a/lib/page/component/dialog.dart b/lib/page/component/dialog.dart index 67909396..07307346 100644 --- a/lib/page/component/dialog.dart +++ b/lib/page/component/dialog.dart @@ -52,7 +52,17 @@ showErrorMessageEnhanced( return; // 需要登录 case 'sign-in': - context.push('/login'); + showBeautyDialog( + context, + type: QuickAlertType.warning, + text: '该功能需要登录账号后使用', + onConfirmBtnTap: () { + context.pop(); + context.push('/login'); + }, + showCancelBtn: true, + confirmBtnText: '立即登录', + ); return; } diff --git a/lib/page/creative_island/draw/draw_list.dart b/lib/page/creative_island/draw/draw_list.dart index c88556fe..5b121287 100644 --- a/lib/page/creative_island/draw/draw_list.dart +++ b/lib/page/creative_island/draw/draw_list.dart @@ -94,19 +94,15 @@ class _DrawListScreenState extends State { titleColor: stringToColor(e.titleColor), tag: e.tag, onTap: () { - if (userSignedIn) { - var uri = Uri.tryParse(e.routeUri); - if (e.note != null && e.note != '') { - uri = uri!.replace( - queryParameters: { - 'note': e.note!, - }..addAll(uri.queryParameters)); - } - - context.push(uri.toString()); - } else { - context.push('/login'); + var uri = Uri.tryParse(e.routeUri); + if (e.note != null && e.note != '') { + uri = uri!.replace( + queryParameters: { + 'note': e.note!, + }..addAll(uri.queryParameters)); } + + context.push(uri.toString()); }, size: e.size, )) diff --git a/lib/page/creative_island/gallery/gallery_item.dart b/lib/page/creative_island/gallery/gallery_item.dart index 284da456..bdb18553 100644 --- a/lib/page/creative_island/gallery/gallery_item.dart +++ b/lib/page/creative_island/gallery/gallery_item.dart @@ -237,12 +237,8 @@ class _GalleryItemScreenState extends State { child: EnhancedButton( title: '制作同款', onPressed: () { - if (Ability().enableAPIServer()) { - context.push( - '/creative-draw/create?mode=text-to-image&id=${state.item.creativeId}&gallery_copy_id=${state.item.id}'); - } else { - context.push('/login'); - } + context.push( + '/creative-draw/create?mode=text-to-image&id=${state.item.creativeId}&gallery_copy_id=${state.item.id}'); }, ), ), @@ -327,9 +323,9 @@ class _TextItemState extends State { cancel(); }, label: const Text(''), - icon: Column( + icon: const Column( mainAxisSize: MainAxisSize.min, - children: const [ + children: [ Icon( Icons.copy, color: Color.fromARGB(255, 255, 255, 255), @@ -355,9 +351,9 @@ class _TextItemState extends State { }); }, label: const Text(''), - icon: Column( + icon: const Column( mainAxisSize: MainAxisSize.min, - children: const [ + children: [ Icon( Icons.translate, color: Color.fromARGB(255, 255, 255, 255), @@ -434,9 +430,9 @@ class _TextItemState extends State { cancel(); }, label: const Text(''), - icon: Column( + icon: const Column( mainAxisSize: MainAxisSize.min, - children: const [ + children: [ Icon( Icons.copy, color: Color.fromARGB(255, 255, 255, 255), diff --git a/lib/page/setting/setting_screen.dart b/lib/page/setting/setting_screen.dart index 4e6cb622..4ef930b1 100644 --- a/lib/page/setting/setting_screen.dart +++ b/lib/page/setting/setting_screen.dart @@ -106,7 +106,9 @@ class _SettingScreenState extends State { if (Ability().enableOpenAI) _buildOpenAISelfHostedSetting(customColors), // 用户 API Keys 配置 - if (Ability().supportAPIKeys) + if (state is AccountLoaded && + state.user != null && + Ability().supportAPIKeys) _buildUserAPIKeySetting(customColors), ], ), diff --git a/lib/repo/api_server.dart b/lib/repo/api_server.dart index 5c2e14a4..920f5bfa 100644 --- a/lib/repo/api_server.dart +++ b/lib/repo/api_server.dart @@ -72,7 +72,8 @@ class APIServer { if (resp.data is Map && resp.data['error'] != null && - resp.statusCode != 402) { + resp.statusCode != 402 && + resp.statusCode != 401) { return resp.data['error'] ?? e.toString(); } @@ -1592,6 +1593,20 @@ class APIServer { ); } + /// 免费聊天次数统计(登录不登录都可以访问) + Future> freeChatCounts() async { + return sendGetRequest( + '/public/info/free-chat-counts', + (resp) { + var items = []; + for (var item in resp.data['data']) { + items.add(FreeModelCount.fromJson(item)); + } + return items; + }, + ); + } + /// 用户免费聊天次数统计(单个模型) Future userFreeStatisticsForModel( {required String model}) async { From cbc971468de27664f80f654612ca5213d5c29f0f Mon Sep 17 00:00:00 2001 From: mylxsw Date: Mon, 4 Dec 2023 16:14:53 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E5=A4=B4=E8=AE=BE=E7=BD=AE=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/helper/ability.dart | 5 + lib/helper/event.dart | 6 +- lib/page/app_scaffold.dart | 17 ++- lib/page/chat/group/chat.dart | 3 + lib/page/chat/home.dart | 4 +- lib/page/chat/home_chat.dart | 3 + lib/page/chat/room_chat.dart | 4 + lib/page/chat/rooms.dart | 9 +- lib/page/component/global_alert.dart | 114 ++++++++++++++++++ lib/page/component/notify_message.dart | 4 +- .../creative_island/draw/artistic_text.dart | 23 +++- .../creative_island/draw/draw_create.dart | 23 +++- .../draw/image_edit_direct.dart | 23 +++- lib/repo/api_server.dart | 33 ++++- 14 files changed, 246 insertions(+), 25 deletions(-) create mode 100644 lib/page/component/global_alert.dart diff --git a/lib/helper/ability.dart b/lib/helper/ability.dart index 0808b572..d3a4ce85 100644 --- a/lib/helper/ability.dart +++ b/lib/helper/ability.dart @@ -20,6 +20,11 @@ class Ability { return _instance; } + /// 是否显示全局警告信息 + bool get showGlobalAlert { + return true; + } + /// 服务状态页 String get serviceStatusPage { return capabilities.serviceStatusPage; diff --git a/lib/helper/event.dart b/lib/helper/event.dart index 04edeea3..a2c502d1 100644 --- a/lib/helper/event.dart +++ b/lib/helper/event.dart @@ -11,12 +11,16 @@ class GlobalEvent { final Map> _listeners = {}; /// 监听事件 - void on(String event, Function(dynamic data) callback) { + Function() on(String event, Function(dynamic data) callback) { if (_listeners[event] == null) { _listeners[event] = []; } _listeners[event]!.add(callback); + + return () { + _listeners[event]!.remove(callback); + }; } /// 触发事件 diff --git a/lib/page/app_scaffold.dart b/lib/page/app_scaffold.dart index 02572cf4..8489ead5 100644 --- a/lib/page/app_scaffold.dart +++ b/lib/page/app_scaffold.dart @@ -24,9 +24,21 @@ class AppScaffold extends StatefulWidget { class _AppScaffoldState extends State { var _showBottomNavigatorBar = true; + Function? cancelHideBottomNavigatorBarEventListener; + Function? cancelShowBottomNavigatorBarEventListener; + + @override + void dispose() { + cancelHideBottomNavigatorBarEventListener?.call(); + cancelShowBottomNavigatorBarEventListener?.call(); + + super.dispose(); + } + @override void initState() { - GlobalEvent().on("hideBottomNavigatorBar", (data) { + cancelHideBottomNavigatorBarEventListener = + GlobalEvent().on("hideBottomNavigatorBar", (data) { if (mounted) { setState(() { _showBottomNavigatorBar = false; @@ -34,7 +46,8 @@ class _AppScaffoldState extends State { } }); - GlobalEvent().on("showBottomNavigatorBar", (data) { + cancelShowBottomNavigatorBarEventListener = + GlobalEvent().on("showBottomNavigatorBar", (data) { if (mounted) { setState(() { _showBottomNavigatorBar = true; diff --git a/lib/page/chat/group/chat.dart b/lib/page/chat/group/chat.dart index 0050ebc8..852d76ce 100644 --- a/lib/page/chat/group/chat.dart +++ b/lib/page/chat/group/chat.dart @@ -13,6 +13,7 @@ import 'package:askaide/page/component/chat/chat_share.dart'; import 'package:askaide/page/component/chat/help_tips.dart'; import 'package:askaide/page/component/chat/message_state_manager.dart'; import 'package:askaide/page/component/enhanced_popup_menu.dart'; +import 'package:askaide/page/component/global_alert.dart'; import 'package:askaide/page/component/multi_item_selector.dart'; import 'package:askaide/page/component/random_avatar.dart'; import 'package:askaide/page/component/dialog.dart'; @@ -148,6 +149,8 @@ class _GroupChatPageState extends State { bottom: false, child: Column( children: [ + if (Ability().showGlobalAlert) + const GlobalAlert(pageKey: 'chat'), // 语音输出中提示 if (showAudioPlayer) EnhancedAudioPlayer( diff --git a/lib/page/chat/home.dart b/lib/page/chat/home.dart index 525fde9c..e1b6ee8d 100644 --- a/lib/page/chat/home.dart +++ b/lib/page/chat/home.dart @@ -16,6 +16,7 @@ import 'package:askaide/page/component/chat/file_upload.dart'; import 'package:askaide/page/component/chat/voice_record.dart'; import 'package:askaide/page/component/column_block.dart'; import 'package:askaide/page/component/enhanced_textfield.dart'; +import 'package:askaide/page/component/global_alert.dart'; import 'package:askaide/page/component/model_indicator.dart'; import 'package:askaide/page/component/notify_message.dart'; import 'package:askaide/page/component/sliver_component.dart'; @@ -409,8 +410,9 @@ class _HomePageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 首页通知消息组件 + if (Ability().showGlobalAlert) const GlobalAlert(pageKey: 'home'), if (showFreeModelNotifyMessage && promotionEvent != null) + // 首页通知消息组件 buildNotifyMessageWidget(context), // 模型选择 Container( diff --git a/lib/page/chat/home_chat.dart b/lib/page/chat/home_chat.dart index f6aac73c..0ac62829 100644 --- a/lib/page/chat/home_chat.dart +++ b/lib/page/chat/home_chat.dart @@ -2,6 +2,7 @@ import 'package:askaide/bloc/chat_message_bloc.dart'; import 'package:askaide/bloc/free_count_bloc.dart'; import 'package:askaide/bloc/notify_bloc.dart'; import 'package:askaide/bloc/room_bloc.dart'; +import 'package:askaide/helper/ability.dart'; import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/global_store.dart'; import 'package:askaide/helper/model.dart'; @@ -17,6 +18,7 @@ import 'package:askaide/page/component/chat/file_upload.dart'; import 'package:askaide/page/component/chat/help_tips.dart'; import 'package:askaide/page/component/chat/message_state_manager.dart'; import 'package:askaide/page/component/enhanced_error.dart'; +import 'package:askaide/page/component/global_alert.dart'; import 'package:askaide/page/component/loading.dart'; import 'package:askaide/page/component/random_avatar.dart'; import 'package:askaide/page/component/dialog.dart'; @@ -258,6 +260,7 @@ class _HomeChatPageState extends State { ) { return Column( children: [ + if (Ability().showGlobalAlert) const GlobalAlert(pageKey: 'chat'), if (showAudioPlayer) EnhancedAudioPlayer( controller: _audioPlayerController, diff --git a/lib/page/chat/room_chat.dart b/lib/page/chat/room_chat.dart index 60824182..e291c772 100644 --- a/lib/page/chat/room_chat.dart +++ b/lib/page/chat/room_chat.dart @@ -1,4 +1,5 @@ import 'package:askaide/bloc/free_count_bloc.dart'; +import 'package:askaide/helper/ability.dart'; import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/haptic_feedback.dart'; import 'package:askaide/helper/image.dart'; @@ -15,6 +16,7 @@ import 'package:askaide/page/component/chat/message_state_manager.dart'; import 'package:askaide/page/component/effect/glass.dart'; import 'package:askaide/page/component/enhanced_popup_menu.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/random_avatar.dart'; import 'package:askaide/page/component/theme/custom_size.dart'; @@ -144,6 +146,8 @@ class _RoomChatPageState extends State { bottom: false, child: Column( children: [ + if (Ability().showGlobalAlert) + const GlobalAlert(pageKey: 'chat'), // 语音输出中提示 if (showAudioPlayer) EnhancedAudioPlayer( diff --git a/lib/page/chat/rooms.dart b/lib/page/chat/rooms.dart index 9edd1552..ca6c36c6 100644 --- a/lib/page/chat/rooms.dart +++ b/lib/page/chat/rooms.dart @@ -6,6 +6,7 @@ import 'package:askaide/page/component/background_container.dart'; import 'package:askaide/page/component/enhanced_button.dart'; import 'package:askaide/page/component/enhanced_error.dart'; import 'package:askaide/page/component/enhanced_popup_menu.dart'; +import 'package:askaide/page/component/global_alert.dart'; import 'package:askaide/page/component/loading.dart'; import 'package:askaide/page/component/room_card.dart'; import 'package:askaide/page/component/sliver_component.dart'; @@ -152,7 +153,13 @@ class _RoomsPageState extends State { .add(RoomsLoadEvent(forceRefresh: true)); }, displacement: 20, - child: buildBody(customColors, state, context), + child: Column( + children: [ + if (Ability().showGlobalAlert) + const GlobalAlert(pageKey: 'rooms'), + Expanded(child: buildBody(customColors, state, context)), + ], + ), ), ); } diff --git a/lib/page/component/global_alert.dart b/lib/page/component/global_alert.dart new file mode 100644 index 00000000..fac9ec03 --- /dev/null +++ b/lib/page/component/global_alert.dart @@ -0,0 +1,114 @@ +import 'package:askaide/helper/event.dart'; +import 'package:askaide/page/component/chat/markdown.dart'; +import 'package:askaide/repo/api_server.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:url_launcher/url_launcher_string.dart'; + +class GlobalAlertEvent { + String id; + String? message; + String type; + List pages; + + GlobalAlertEvent({ + required this.id, + this.message, + required this.type, + required this.pages, + }); + + toJSON() { + return { + 'id': id, + 'message': message, + 'type': type, + 'pages': pages, + }; + } +} + +class GlobalAlert extends StatefulWidget { + final String pageKey; + const GlobalAlert({super.key, required this.pageKey}); + + @override + State createState() => _GlobalAlertState(); +} + +class _GlobalAlertState extends State { + Function? globalAlertListener; + + late GlobalAlertEvent alertEvent; + + @override + void initState() { + alertEvent = APIServer().globalAlertEvent; + + globalAlertListener = GlobalEvent().on('global-alert', (data) { + final event = data as GlobalAlertEvent; + if (event.pages.isNotEmpty && !event.pages.contains(widget.pageKey)) { + return; + } + + if (mounted) { + setState(() { + alertEvent = data; + }); + } + }); + + super.initState(); + } + + @override + void dispose() { + globalAlertListener?.call(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (alertEvent.id == '' || + alertEvent.message == null || + alertEvent.message == '') { + return const SizedBox(); + } + + return Container( + margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 5), + padding: const EdgeInsets.symmetric(horizontal: 10), + width: double.infinity, + decoration: BoxDecoration( + color: resolveBackgroundColor(), + borderRadius: BorderRadius.circular(5), + ), + child: Markdown( + data: alertEvent.message!, + textStyle: const TextStyle( + color: Colors.white, + ), + onUrlTap: (value) { + if (value.startsWith("aidea-app://")) { + var route = value.substring('aidea-app://'.length); + context.push(route); + } else { + launchUrlString(value); + } + }, + ), + ); + } + + Color resolveBackgroundColor() { + switch (alertEvent.type) { + case 'error': + case 'warning': + return const Color.fromARGB(255, 252, 145, 79); + case 'info': + return const Color.fromARGB(255, 18, 83, 135); + default: + return Colors.green; + } + } +} diff --git a/lib/page/component/notify_message.dart b/lib/page/component/notify_message.dart index 7aa1aa73..3acb3a70 100644 --- a/lib/page/component/notify_message.dart +++ b/lib/page/component/notify_message.dart @@ -6,6 +6,7 @@ class NotifyMessageWidget extends StatelessWidget { final Function()? onClose; final Widget child; final String? backgroundImageUrl; + final Color? backgroundColor; final double height; final Widget? title; final bool closeable; @@ -17,6 +18,7 @@ class NotifyMessageWidget extends StatelessWidget { this.height = 100, this.title, this.closeable = true, + this.backgroundColor, }); @override @@ -38,7 +40,7 @@ class NotifyMessageWidget extends StatelessWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), // gradient: buildGradientStyle(), - // color: Color.fromARGB(255, 252, 188, 188), + color: backgroundColor, image: backgroundImageUrl != null ? DecorationImage( fit: BoxFit.cover, diff --git a/lib/page/creative_island/draw/artistic_text.dart b/lib/page/creative_island/draw/artistic_text.dart index f0019e02..5faa2e86 100644 --- a/lib/page/creative_island/draw/artistic_text.dart +++ b/lib/page/creative_island/draw/artistic_text.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:askaide/helper/ability.dart'; import 'package:askaide/helper/haptic_feedback.dart'; import 'package:askaide/lang/lang.dart'; import 'package:askaide/page/component/background_container.dart'; @@ -7,6 +8,7 @@ import 'package:askaide/page/component/column_block.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'; @@ -148,12 +150,21 @@ class _ArtisticTextScreenState extends State { setting: widget.setting, enabled: true, maxWidth: CustomSize.smallWindowSize, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), - height: double.infinity, - child: SingleChildScrollView( - child: buildEditPanel(context, customColors), - ), + 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), + ), + ), + ), + ], ), ), ); diff --git a/lib/page/creative_island/draw/draw_create.dart b/lib/page/creative_island/draw/draw_create.dart index 679dd456..97194e8e 100644 --- a/lib/page/creative_island/draw/draw_create.dart +++ b/lib/page/creative_island/draw/draw_create.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:askaide/helper/ability.dart'; import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/haptic_feedback.dart'; import 'package:askaide/helper/upload.dart'; @@ -9,6 +10,7 @@ import 'package:askaide/page/component/column_block.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'; @@ -192,12 +194,21 @@ class _DrawCreateScreenState extends State { setting: widget.setting, enabled: true, maxWidth: CustomSize.smallWindowSize, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), - height: double.infinity, - child: SingleChildScrollView( - child: buildEditPanel(context, customColors), - ), + 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), + ), + ), + ), + ], ), ), ); diff --git a/lib/page/creative_island/draw/image_edit_direct.dart b/lib/page/creative_island/draw/image_edit_direct.dart index f0609225..171b8508 100644 --- a/lib/page/creative_island/draw/image_edit_direct.dart +++ b/lib/page/creative_island/draw/image_edit_direct.dart @@ -1,9 +1,11 @@ +import 'package:askaide/helper/ability.dart'; import 'package:askaide/helper/haptic_feedback.dart'; import 'package:askaide/helper/upload.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/enhanced_button.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'; @@ -68,12 +70,21 @@ class _ImageEditDirectScreenState extends State { setting: widget.setting, enabled: true, maxWidth: CustomSize.smallWindowSize, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), - height: double.infinity, - child: SingleChildScrollView( - child: buildEditPanel(context, customColors), - ), + 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), + ), + ), + ), + ], ), ), ); diff --git a/lib/repo/api_server.dart b/lib/repo/api_server.dart index 920f5bfa..7cc67167 100644 --- a/lib/repo/api_server.dart +++ b/lib/repo/api_server.dart @@ -3,9 +3,11 @@ import 'dart:convert'; import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/env.dart'; import 'package:askaide/helper/error.dart'; +import 'package:askaide/helper/event.dart'; import 'package:askaide/helper/http.dart'; import 'package:askaide/helper/logger.dart'; import 'package:askaide/helper/platform.dart'; +import 'package:askaide/page/component/global_alert.dart'; import 'package:askaide/repo/api/article.dart'; import 'package:askaide/repo/api/creative.dart'; import 'package:askaide/repo/api/image_model.dart'; @@ -32,6 +34,11 @@ class APIServer { return _instance; } + GlobalAlertEvent _globalAlertEvent = + GlobalAlertEvent(id: '', type: 'info', pages: [], message: ''); + + GlobalAlertEvent get globalAlertEvent => _globalAlertEvent; + late String url; late String apiToken; late String language; @@ -292,7 +299,31 @@ class APIServer { return Future.error(resp.data['error']); } - // Logger.instance.d("API Response: ${resp.data}"); + try { + var msg = resp.headers.value('aidea-global-alert-msg'); + if (msg != null) { + msg = utf8.decode(base64Decode(msg)); + } + + // Logger.instance.d("API Response: ${resp.data}"); + final globalAlertEvent = GlobalAlertEvent( + id: resp.headers.value('aidea-global-alert-id') ?? '', + type: resp.headers.value('aidea-global-alert-type') ?? 'info', + pages: (resp.headers.value('aidea-global-alert-pages') ?? '') + .split(',') + .where((e) => e != '') + .toList(), + message: msg, + ); + + if (globalAlertEvent.id != '' && + globalAlertEvent.id != _globalAlertEvent.id) { + _globalAlertEvent = globalAlertEvent; + GlobalEvent().emit('global-alert', _globalAlertEvent); + } + } catch (e) { + Logger.instance.e(e); + } return parser(resp); } catch (e, stackTrace) { From d95f7177a24f9f57ab96d5b02d27245ec1be78e8 Mon Sep 17 00:00:00 2001 From: mylxsw Date: Thu, 14 Dec 2023 17:57:19 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E5=BE=AE=E8=B0=83,=E7=89=88=E6=9C=AC=E5=8F=B7=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=B8=BA=201.0.10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/helper/constant.dart | 2 +- lib/page/component/chat/chat_preview.dart | 2 +- lib/page/component/chat/file_upload.dart | 3 +++ lib/page/creative_island/gallery/gallery_item.dart | 1 - pubspec.yaml | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/helper/constant.dart b/lib/helper/constant.dart index 3f6090d5..8505ccec 100644 --- a/lib/helper/constant.dart +++ b/lib/helper/constant.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; // 客户端应用版本号 -const clientVersion = '1.0.9'; +const clientVersion = '1.0.10'; // 本地数据库版本号 const databaseVersion = 26; diff --git a/lib/page/component/chat/chat_preview.dart b/lib/page/component/chat/chat_preview.dart index 4d256523..bbf76cce 100644 --- a/lib/page/component/chat/chat_preview.dart +++ b/lib/page/component/chat/chat_preview.dart @@ -868,7 +868,7 @@ class _ChatPreviewState extends State { /// 获取图片预览的最大宽度 double _chatBoxImagePreviewWidth(BuildContext context, int imageCount) { final expect = _chatBoxMaxWidth(context) / 1.3; - final max = imageCount > 1 ? 400.0 : 300.0; + final max = imageCount > 1 ? 600.0 : 400.0; return expect > max ? max : expect; } } diff --git a/lib/page/component/chat/file_upload.dart b/lib/page/component/chat/file_upload.dart index 709c8dd3..c0dba018 100644 --- a/lib/page/component/chat/file_upload.dart +++ b/lib/page/component/chat/file_upload.dart @@ -54,6 +54,7 @@ class FileUploadPreview extends StatelessWidget { GridView.count( crossAxisCount: 2, shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), children: children.sublist(0, children.length - 1), ), children.last, @@ -64,12 +65,14 @@ class FileUploadPreview extends StatelessWidget { return GridView.count( crossAxisCount: 2, shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), children: children, ); } return ListView( shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), children: children, ); } diff --git a/lib/page/creative_island/gallery/gallery_item.dart b/lib/page/creative_island/gallery/gallery_item.dart index bdb18553..2c61e9f1 100644 --- a/lib/page/creative_island/gallery/gallery_item.dart +++ b/lib/page/creative_island/gallery/gallery_item.dart @@ -1,5 +1,4 @@ import 'package:askaide/bloc/gallery_bloc.dart'; -import 'package:askaide/helper/ability.dart'; import 'package:askaide/helper/constant.dart'; import 'package:askaide/helper/haptic_feedback.dart'; import 'package:askaide/helper/helper.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index e6485590..85ea6e43 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.9+1 +version: 1.0.10+1 environment: sdk: '>=3.0.0 <4.0.0' From 0aeab44c53edb2056a8ea1aba03617261ad7cf64 Mon Sep 17 00:00:00 2001 From: mylxsw Date: Sat, 16 Dec 2023 15:02:18 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E6=9C=AA=E7=99=BB=E5=BD=95=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=B8=8B,=E5=85=81=E8=AE=B8=E8=BF=9B=E5=85=A5?= =?UTF-8?q?=E5=88=B0=E4=BB=98=E6=AC=BE=E9=A1=B5=E9=9D=A2=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E6=9C=89=E5=93=AA=E4=BA=9B=E5=8F=AF=E8=B4=AD=E4=B9=B0=E7=9A=84?= =?UTF-8?q?=E4=BA=A7=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bloc/chat_message_bloc.dart | 4 +- lib/bloc/free_count_bloc.dart | 4 +- lib/bloc/payment_bloc.dart | 4 +- lib/bloc/payment_state.dart | 2 +- lib/bloc/room_bloc.dart | 10 ++-- lib/helper/ability.dart | 4 +- lib/helper/error.dart | 2 +- lib/page/balance/payment.dart | 60 ++++++++++---------- lib/page/balance/price_block.dart | 2 +- lib/page/chat/group/chat.dart | 3 +- lib/page/chat/group/create.dart | 3 +- lib/page/chat/group/edit.dart | 3 +- lib/page/chat/room_create.dart | 6 +- lib/page/chat/room_edit.dart | 4 +- lib/page/chat/rooms.dart | 2 +- lib/page/component/account_quota_card.dart | 46 +++++++++------ lib/page/component/chat/chat_share.dart | 3 +- lib/page/component/model_item.dart | 3 +- lib/page/creative_island/draw/draw_list.dart | 2 +- lib/page/setting/setting_screen.dart | 24 ++++---- lib/repo/api/payment.dart | 20 +++---- lib/repo/api_server.dart | 16 ++---- lib/repo/openai_repo.dart | 2 +- 23 files changed, 115 insertions(+), 114 deletions(-) diff --git a/lib/bloc/chat_message_bloc.dart b/lib/bloc/chat_message_bloc.dart index cdbc94ec..23d61a54 100644 --- a/lib/bloc/chat_message_bloc.dart +++ b/lib/bloc/chat_message_bloc.dart @@ -284,7 +284,7 @@ class ChatMessageBloc extends BlocExt { // 更新 Room 最后活跃时间 // 这里没有使用 await,因为不需要等待更新完成,让 room 的更新异步的去处理吧 - if (!Ability().enableAPIServer()) { + if (!Ability().isUserLogon()) { chatMsgRepo.updateRoomLastActiveTime(roomId); } @@ -488,7 +488,7 @@ class ChatMessageBloc extends BlocExt { Future queryRoomById( ChatMessageRepository chatMsgRepo, int roomId) async { Room? room; - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { final roomInServer = await APIServer().room(roomId: roomId); room = Room( roomInServer.name, diff --git a/lib/bloc/free_count_bloc.dart b/lib/bloc/free_count_bloc.dart index d22d49a5..7c04a643 100644 --- a/lib/bloc/free_count_bloc.dart +++ b/lib/bloc/free_count_bloc.dart @@ -13,7 +13,7 @@ class FreeCountBloc extends Bloc { FreeCountBloc() : super(FreeCountInitial()) { // 重新加载所有的模型免费使用次数 on((event, emit) async { - if (!Ability().enableAPIServer()) { + if (!Ability().isUserLogon()) { emit(FreeCountLoadedState( counts: await APIServer().freeChatCounts(), needSignin: event.checkSigninStatus, @@ -28,7 +28,7 @@ class FreeCountBloc extends Bloc { // 重新加载指定模型的免费使用次数 on((event, emit) async { if (Ability().usingLocalOpenAIModel(event.model) || - !Ability().enableAPIServer()) { + !Ability().isUserLogon()) { emit(FreeCountLoadedState(counts: counts)); return; } diff --git a/lib/bloc/payment_bloc.dart b/lib/bloc/payment_bloc.dart index ed04ba1f..a8c96e5d 100644 --- a/lib/bloc/payment_bloc.dart +++ b/lib/bloc/payment_bloc.dart @@ -12,7 +12,7 @@ class PaymentBloc extends Bloc { PaymentBloc() : super(PaymentInitial()) { on((event, emit) async { if (PlatformTool.isIOS()) { - final products = await APIServer().applePayProducts(); + final products = await APIServer().paymentProducts(); if (products.consume.isEmpty) { emit(PaymentAppleProductsLoaded( const [], @@ -69,7 +69,7 @@ class PaymentBloc extends Bloc { loading: false, )); } else { - final products = await APIServer().otherPayProducts(); + final products = await APIServer().paymentProducts(); if (products.consume.isEmpty) { emit(PaymentAppleProductsLoaded( const [], diff --git a/lib/bloc/payment_state.dart b/lib/bloc/payment_state.dart index cd54f2d6..6d250aa1 100644 --- a/lib/bloc/payment_state.dart +++ b/lib/bloc/payment_state.dart @@ -7,7 +7,7 @@ class PaymentInitial extends PaymentState {} class PaymentAppleProductsLoaded extends PaymentState { final List products; - final List localProducts; + final List localProducts; final Object? error; final bool loading; final String? note; diff --git a/lib/bloc/room_bloc.dart b/lib/bloc/room_bloc.dart index 405c7b09..3bddcb72 100644 --- a/lib/bloc/room_bloc.dart +++ b/lib/bloc/room_bloc.dart @@ -38,7 +38,7 @@ class RoomBloc extends BlocExt { )); } - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { final room = await APIServer().room(roomId: event.roomId); if (event.chatHistoryId != null && event.chatHistoryId! > 0) { final chatHistory = @@ -128,7 +128,7 @@ class RoomBloc extends BlocExt { emit(RoomsLoading()); try { - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { await APIServer().createRoom( name: event.name, vendor: event.model.split(':').first, @@ -161,7 +161,7 @@ class RoomBloc extends BlocExt { emit(RoomsLoading()); try { - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { await APIServer().deleteRoom(roomId: event.roomId); } else { var room = await chatMsgRepo.room(event.roomId); @@ -180,7 +180,7 @@ class RoomBloc extends BlocExt { // 更新聊天室信息 on((event, emit) async { - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { final room = await APIServer().updateRoom( roomId: event.roomId, name: event.name!, @@ -311,7 +311,7 @@ class RoomBloc extends BlocExt { Future createRoomsLoadedState({bool cache = true}) async { try { - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { final resp = await APIServer().rooms(cache: cache); return RoomsLoaded( resp.rooms diff --git a/lib/helper/ability.dart b/lib/helper/ability.dart index d3a4ce85..7f3b1992 100644 --- a/lib/helper/ability.dart +++ b/lib/helper/ability.dart @@ -109,8 +109,8 @@ class Ability { return enableOtherPay; } - /// 是否支持API Server - bool enableAPIServer() { + /// 是否用户已经登陆 + bool isUserLogon() { return setting.stringDefault(settingAPIServerToken, '') != ''; } diff --git a/lib/helper/error.dart b/lib/helper/error.dart index 6ebca232..d8e50fed 100644 --- a/lib/helper/error.dart +++ b/lib/helper/error.dart @@ -27,7 +27,7 @@ Object? resolveHTTPStatusCode(int statusCode, return const LanguageText(AppLocale.openAIAuthFailed); } - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { return const LanguageText(AppLocale.accountNeedReSignin, action: 're-signin'); } diff --git a/lib/page/balance/payment.dart b/lib/page/balance/payment.dart index f174b64d..48dcac6d 100644 --- a/lib/page/balance/payment.dart +++ b/lib/page/balance/payment.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:askaide/bloc/payment_bloc.dart'; +import 'package:askaide/helper/ability.dart'; import 'package:askaide/helper/helper.dart'; import 'package:askaide/helper/logger.dart'; import 'package:askaide/helper/platform.dart'; @@ -22,6 +23,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localization/flutter_localization.dart'; import 'package:go_router/go_router.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; +import 'package:quickalert/models/quickalert_type.dart'; import 'package:tobias/tobias.dart'; import 'package:url_launcher/url_launcher_string.dart'; @@ -181,37 +183,20 @@ class _PaymentScreenState extends State { ), ), actions: [ - TextButton( - style: ButtonStyle( - overlayColor: MaterialStateProperty.all(Colors.transparent), - ), - onPressed: () { - context.push('/quota-details'); - }, - child: Text( - AppLocale.paymentHistory.getString(context), - style: TextStyle(color: customColors.weakLinkColor), - textScaleFactor: 0.9, + if (Ability().isUserLogon()) + TextButton( + style: ButtonStyle( + overlayColor: MaterialStateProperty.all(Colors.transparent), + ), + onPressed: () { + context.push('/quota-details'); + }, + child: Text( + AppLocale.paymentHistory.getString(context), + style: TextStyle(color: customColors.weakLinkColor), + textScaleFactor: 0.9, + ), ), - ), - // TextButton( - // style: ButtonStyle( - // overlayColor: MaterialStateProperty.all(Colors.transparent), - // ), - // onPressed: () { - // _startPaymentLoading(); - // // 恢复购买 - // InAppPurchase.instance.restorePurchases().whenComplete(() { - // _closePaymentLoading(); - // showSuccessMessage('恢复完成'); - // }); - // }, - // child: Text( - // '恢复购买', - // style: TextStyle(color: customColors.weakLinkColor), - // textScaleFactor: 0.9, - // ), - // ), ], ), backgroundColor: customColors.backgroundContainerColor, @@ -312,6 +297,21 @@ class _PaymentScreenState extends State { return; } + if (!Ability().isUserLogon()) { + showBeautyDialog( + context, + type: QuickAlertType.warning, + text: '该功能需要登录账号后使用', + onConfirmBtnTap: () { + context.pop(); + context.push('/login'); + }, + showCancelBtn: true, + confirmBtnText: '立即登录', + ); + return; + } + if (PlatformTool.isIOS() || PlatformTool.isAndroid() || PlatformTool.isMacOS()) { diff --git a/lib/page/balance/price_block.dart b/lib/page/balance/price_block.dart index fed5a5d7..3591414c 100644 --- a/lib/page/balance/price_block.dart +++ b/lib/page/balance/price_block.dart @@ -8,7 +8,7 @@ class PriceBlock extends StatelessWidget { final CustomColors customColors; final ProductDetails detail; final ProductDetails? selectedProduct; - final AppleProduct product; + final PaymentProduct product; final bool loading; const PriceBlock({ diff --git a/lib/page/chat/group/chat.dart b/lib/page/chat/group/chat.dart index 852d76ce..3e38a1d4 100644 --- a/lib/page/chat/group/chat.dart +++ b/lib/page/chat/group/chat.dart @@ -514,8 +514,7 @@ class _GroupChatPageState extends State { return RandomAvatar( id: id ?? 0, size: size, - usage: - Ability().enableAPIServer() ? AvatarUsage.room : AvatarUsage.legacy, + usage: Ability().isUserLogon() ? AvatarUsage.room : AvatarUsage.legacy, ); } diff --git a/lib/page/chat/group/create.dart b/lib/page/chat/group/create.dart index 804a81a2..0fbe5a15 100644 --- a/lib/page/chat/group/create.dart +++ b/lib/page/chat/group/create.dart @@ -213,8 +213,7 @@ class _GroupCreatePageState extends State { return RandomAvatar( id: id ?? 0, size: size, - usage: - Ability().enableAPIServer() ? AvatarUsage.room : AvatarUsage.legacy, + usage: Ability().isUserLogon() ? AvatarUsage.room : AvatarUsage.legacy, ); } } diff --git a/lib/page/chat/group/edit.dart b/lib/page/chat/group/edit.dart index 1c602175..9fb3a064 100644 --- a/lib/page/chat/group/edit.dart +++ b/lib/page/chat/group/edit.dart @@ -486,8 +486,7 @@ class _GroupEditPageState extends State { return RandomAvatar( id: id ?? 0, size: size, - usage: - Ability().enableAPIServer() ? AvatarUsage.room : AvatarUsage.legacy, + usage: Ability().isUserLogon() ? AvatarUsage.room : AvatarUsage.legacy, ); } diff --git a/lib/page/chat/room_create.dart b/lib/page/chat/room_create.dart index 2d275368..73d384f5 100644 --- a/lib/page/chat/room_create.dart +++ b/lib/page/chat/room_create.dart @@ -75,7 +75,7 @@ class _RoomCreatePageState extends State { void initState() { super.initState(); - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { APIServer().avatars().then((value) { avatarPresets = value; }); @@ -111,7 +111,7 @@ class _RoomCreatePageState extends State { maxWidth: 0, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), - child: Ability().enableAPIServer() + child: Ability().isUserLogon() ? SafeArea( top: false, child: DefaultTabController( @@ -288,7 +288,7 @@ class _RoomCreatePageState extends State { hintText: AppLocale.required.getString(context), textDirection: TextDirection.rtl, ), - if (Ability().enableAPIServer()) + if (Ability().isUserLogon()) EnhancedInput( padding: const EdgeInsets.only(top: 10, bottom: 5), title: Text( diff --git a/lib/page/chat/room_edit.dart b/lib/page/chat/room_edit.dart index 98ea4362..56a8d325 100644 --- a/lib/page/chat/room_edit.dart +++ b/lib/page/chat/room_edit.dart @@ -75,7 +75,7 @@ class _RoomEditPageState extends State { .add(RoomLoadEvent(widget.roomId, cascading: false)); // 获取预设头像 - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { APIServer().avatars().then((value) { avatarPresets = value; }); @@ -173,7 +173,7 @@ class _RoomEditPageState extends State { hintText: AppLocale.required.getString(context), textDirection: TextDirection.rtl, ), - if (Ability().enableAPIServer()) + if (Ability().isUserLogon()) EnhancedInput( padding: const EdgeInsets.only(top: 10, bottom: 5), diff --git a/lib/page/chat/rooms.dart b/lib/page/chat/rooms.dart index ca6c36c6..904f28be 100644 --- a/lib/page/chat/rooms.dart +++ b/lib/page/chat/rooms.dart @@ -84,7 +84,7 @@ class _RoomsPageState extends State { }); }, ), - if (Ability().enableAPIServer() && + if (Ability().isUserLogon() && !Ability().enableLocalOpenAI) EnhancedPopupMenuItem( title: '发起群聊', diff --git a/lib/page/component/account_quota_card.dart b/lib/page/component/account_quota_card.dart index 120b328d..54aea4b4 100644 --- a/lib/page/component/account_quota_card.dart +++ b/lib/page/component/account_quota_card.dart @@ -11,10 +11,9 @@ import 'package:go_router/go_router.dart'; import 'package:url_launcher/url_launcher.dart'; class AccountQuotaCard extends StatelessWidget { - final UserInfo userInfo; + final UserInfo? userInfo; final VoidCallback? onPaymentReturn; - const AccountQuotaCard( - {super.key, required this.userInfo, this.onPaymentReturn}); + const AccountQuotaCard({super.key, this.userInfo, this.onPaymentReturn}); @override Widget build(BuildContext context) { @@ -32,15 +31,20 @@ class AccountQuotaCard extends StatelessWidget { offset: const Offset(0, 5), ), ], - image: userInfo.control.userCardBg != null + image: userInfo != null && userInfo!.control.userCardBg != null ? DecorationImage( // opacity: 0.83, image: CachedNetworkImageProviderEnhanced( - userInfo.control.userCardBg!), + userInfo!.control.userCardBg!), fit: BoxFit.cover, ) - : null, - gradient: userInfo.control.userCardBg == null + : DecorationImage( + image: CachedNetworkImageProviderEnhanced( + "https://ssl.aicode.cc/ai-server/assets/quota-card-bg.webp-thumb1000", + ), + fit: BoxFit.cover, + ), + gradient: userInfo == null || userInfo!.control.userCardBg == null ? const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, @@ -94,20 +98,26 @@ class AccountQuotaCard extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - Coin(count: userInfo.quota.quotaRemain()), + if (userInfo != null) + Coin( + count: userInfo!.quota.quotaRemain(), + ) + else + const Text('-'), const SizedBox(width: 5), - InkWell( - onTap: () { - context.push('/quota-usage-statistics'); - }, - child: Text( - AppLocale.coinsUsage.getString(context), - style: const TextStyle( - fontSize: 12, - color: Color.fromARGB(129, 220, 220, 220), + if (userInfo != null) + InkWell( + onTap: () { + context.push('/quota-usage-statistics'); + }, + child: Text( + AppLocale.coinsUsage.getString(context), + style: const TextStyle( + fontSize: 12, + color: Color.fromARGB(129, 220, 220, 220), + ), ), ), - ), ], ) ], diff --git a/lib/page/component/chat/chat_share.dart b/lib/page/component/chat/chat_share.dart index 446d5662..8f27eadd 100644 --- a/lib/page/component/chat/chat_share.dart +++ b/lib/page/component/chat/chat_share.dart @@ -457,8 +457,7 @@ class _ChatShareScreenState extends State { return RandomAvatar( id: id ?? 0, size: size, - usage: - Ability().enableAPIServer() ? AvatarUsage.room : AvatarUsage.legacy, + usage: Ability().isUserLogon() ? AvatarUsage.room : AvatarUsage.legacy, ); } } diff --git a/lib/page/component/model_item.dart b/lib/page/component/model_item.dart index 84a41a17..9fe02516 100644 --- a/lib/page/component/model_item.dart +++ b/lib/page/component/model_item.dart @@ -114,8 +114,7 @@ class ModelItem extends StatelessWidget { return RandomAvatar( id: id ?? 0, size: size, - usage: - Ability().enableAPIServer() ? AvatarUsage.room : AvatarUsage.legacy, + usage: Ability().isUserLogon() ? AvatarUsage.room : AvatarUsage.legacy, ); } } diff --git a/lib/page/creative_island/draw/draw_list.dart b/lib/page/creative_island/draw/draw_list.dart index 5b121287..e86a27a8 100644 --- a/lib/page/creative_island/draw/draw_list.dart +++ b/lib/page/creative_island/draw/draw_list.dart @@ -24,7 +24,7 @@ class DrawListScreen extends StatefulWidget { class _DrawListScreenState extends State { @override void initState() { - if (Ability().enableAPIServer()) { + if (Ability().isUserLogon()) { userSignedIn = true; } diff --git a/lib/page/setting/setting_screen.dart b/lib/page/setting/setting_screen.dart index 4ef930b1..caece919 100644 --- a/lib/page/setting/setting_screen.dart +++ b/lib/page/setting/setting_screen.dart @@ -21,6 +21,7 @@ import 'package:askaide/page/component/theme/custom_theme.dart'; import 'package:askaide/page/component/theme/theme.dart'; import 'package:askaide/helper/constant.dart'; import 'package:askaide/page/component/dialog.dart'; +import 'package:askaide/repo/api/user.dart'; import 'package:askaide/repo/api_server.dart'; import 'package:askaide/repo/settings_repo.dart'; import 'package:flutter/cupertino.dart'; @@ -78,8 +79,7 @@ class _SettingScreenState extends State { builder: (_, state) { return buildSettingsList([ // 智慧果信息、充值入口 - if (state is AccountLoaded && state.user != null) - _buildAccountQuotaCard(context, state), + _buildAccountQuotaCard(context, state), // 账号信息 SettingsSection( @@ -100,7 +100,7 @@ class _SettingScreenState extends State { // 语言设置 _buildCommonLanguageSetting(), // 常用模型 - if (Ability().enableAPIServer()) + if (Ability().isUserLogon()) _buildCustomHomeModelsSetting(customColors), // OpenAI 自定义配置 if (Ability().enableOpenAI) @@ -307,17 +307,21 @@ class _SettingScreenState extends State { } CustomSettingsSection _buildAccountQuotaCard( - BuildContext context, AccountLoaded state) { - if (state.user == null) { - return CustomSettingsSection( - child: Container(), - ); + BuildContext context, + AccountState state, + ) { + UserInfo? userInfo; + if (state is AccountLoaded) { + userInfo = state.user; } + return CustomSettingsSection( child: AccountQuotaCard( - userInfo: state.user!, + userInfo: userInfo, onPaymentReturn: () { - context.read().add(AccountLoadEvent(cache: false)); + if (userInfo != null) { + context.read().add(AccountLoadEvent(cache: false)); + } }, ), ); diff --git a/lib/repo/api/payment.dart b/lib/repo/api/payment.dart index c290b335..3dc98338 100644 --- a/lib/repo/api/payment.dart +++ b/lib/repo/api/payment.dart @@ -20,7 +20,7 @@ class OtherPayCreatedReponse { } } -class AppleProduct { +class PaymentProduct { String id; String name; int quota; @@ -30,7 +30,7 @@ class AppleProduct { bool recommend; String? description; - AppleProduct({ + PaymentProduct({ required this.id, required this.name, required this.quota, @@ -54,8 +54,8 @@ class AppleProduct { 'description': description, }; - static AppleProduct fromJson(Map json) { - return AppleProduct( + static PaymentProduct fromJson(Map json) { + return PaymentProduct( id: json['id'], name: json['name'], quota: json['quota'], @@ -68,21 +68,21 @@ class AppleProduct { } } -class ApplePayProducts { - final List consume; +class PaymentProducts { + final List consume; final String? note; - ApplePayProducts(this.consume, {this.note}); + PaymentProducts(this.consume, {this.note}); toJson() => { 'consume': consume, 'note': note, }; - static ApplePayProducts fromJson(Map json) { - return ApplePayProducts( + static PaymentProducts fromJson(Map json) { + return PaymentProducts( (json['consume'] as List) - .map((e) => AppleProduct.fromJson(e)) + .map((e) => PaymentProduct.fromJson(e)) .toList(), note: json['note'], ); diff --git a/lib/repo/api_server.dart b/lib/repo/api_server.dart index 7cc67167..3f50f8a4 100644 --- a/lib/repo/api_server.dart +++ b/lib/repo/api_server.dart @@ -973,19 +973,11 @@ class APIServer { ); } - /// Apple 支付项目列表 - Future applePayProducts() async { + /// 支付项目列表 + Future paymentProducts() async { return sendGetRequest( - '/v1/payment/apple/products', - (resp) => ApplePayProducts.fromJson(resp.data), - ); - } - - /// 其它支付项目列表 - Future otherPayProducts() async { - return sendGetRequest( - '/v1/payment/others/products', - (resp) => ApplePayProducts.fromJson(resp.data), + '/v1/payment/products', + (resp) => PaymentProducts.fromJson(resp.data), ); } diff --git a/lib/repo/openai_repo.dart b/lib/repo/openai_repo.dart index 88c778c1..ec73166a 100644 --- a/lib/repo/openai_repo.dart +++ b/lib/repo/openai_repo.dart @@ -263,7 +263,7 @@ class OpenAIRepository { } } - if (!Ability().enableAPIServer()) { + if (!Ability().isUserLogon()) { canUseWebsocket = false; } From 1ae18ee13c1de844a063267be91469826ad0d0f2 Mon Sep 17 00:00:00 2001 From: mylxsw Date: Mon, 18 Dec 2023 17:37:50 +0800 Subject: [PATCH 7/8] =?UTF-8?q?bugfix:=20=E8=81=8A=E4=B8=80=E8=81=8A?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=B8=AD,=E8=81=8A=E5=A4=A9=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=98=BE=E7=A4=BA=E5=89=A9=E4=BD=99=E5=85=8D=E8=B4=B9?= =?UTF-8?q?=E6=AC=A1=E6=95=B0=E6=97=B6,=E5=9B=A0=E4=B8=BA=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E4=BA=86=E9=94=99=E8=AF=AF=E7=9A=84=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B(gpt-3.5-turbo),=E5=AF=BC=E8=87=B4=20Gpt-4=20?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=89=A9=E4=BD=99=E6=AC=A1=E6=95=B0=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/page/chat/home_chat.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/page/chat/home_chat.dart b/lib/page/chat/home_chat.dart index 0ac62829..9b5d6e16 100644 --- a/lib/page/chat/home_chat.dart +++ b/lib/page/chat/home_chat.dart @@ -341,7 +341,8 @@ class _HomeChatPageState extends State { builder: (context, freeState) { var hintText = '有问题尽管问我'; if (freeState is FreeCountLoadedState) { - final matched = freeState.model(room.room.model); + final matched = + freeState.model(widget.model ?? room.room.model); if (matched != null && matched.leftCount > 0 && matched.maxCount > 0) { From 9d3efb78db89d37e9cca2bb956c8cedac574dd02 Mon Sep 17 00:00:00 2001 From: mylxsw Date: Tue, 19 Dec 2023 17:35:47 +0800 Subject: [PATCH 8/8] update readme.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7d28e685..e7c3c6c3 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,10 @@ - 支持 OpenAI 的 GPT-3.5,GPT-4 大语言模型 - 支持 Anthropic 的 Claude instant,Claude 2.0 大语言模型 -- 支持国产模型:通义千问,文心一言,讯飞星火,商汤日日新,腾讯混元,百川53B,360智脑 -- 支持开源大模型:Llama2,ChatGLM2,AquilaChat 7B,Bloomz 7B 等,后续还将开放更多 -- 支持文生图、图生图、超分辨率、黑白图片上色等功能,集成 Stable Diffusion 模型,支持 SDXL 1.0 +- 支持 Google 的 Gemini Pro 以及视觉大语言模型 +- 支持国产模型:通义千问,文心一言,讯飞星火,商汤日日新,腾讯混元,百川53B,360智脑,天工等 +- 支持开源大模型:Yi 34B,Llama2,ChatGLM2,AquilaChat 7B,Bloomz 7B 等,后续还将开放更多 +- 支持文生图、图生图、超分辨率、黑白图片上色、艺术字、艺术二维码等功能,支持 SDXL 1.0、Dall·E 3 等 下载体验地址: