From 44421e39d6f9c73aa73dfc284ee28cc0677cb134 Mon Sep 17 00:00:00 2001 From: "Mr.Jebelli" Date: Mon, 16 Feb 2026 14:40:26 +0330 Subject: [PATCH] fixed chatbot ai selector --- .../auth/on_boarding/on_boarding_page.dart | 4 +- lib/ui/screens/chat/chat_page.dart | 594 ++++++++++-------- lib/ui/screens/family/add_family.dart | 154 +++-- .../screens/gmedia/chats/video_chat_page.dart | 1 - 4 files changed, 454 insertions(+), 299 deletions(-) diff --git a/lib/ui/screens/auth/on_boarding/on_boarding_page.dart b/lib/ui/screens/auth/on_boarding/on_boarding_page.dart index 907dd74..a00a212 100644 --- a/lib/ui/screens/auth/on_boarding/on_boarding_page.dart +++ b/lib/ui/screens/auth/on_boarding/on_boarding_page.dart @@ -233,11 +233,11 @@ class _OnBoardingPageState extends State { children: [ TextSpan( text: sliders[index].description, - style: AppTextStyles.body3.copyWith( + style: AppTextStyles.body4.copyWith( color: Theme.of(context).colorScheme.onSurface)) ], - style: AppTextStyles.body3.copyWith( + style: AppTextStyles.body4.copyWith( color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold)), textAlign: TextAlign.justify, diff --git a/lib/ui/screens/chat/chat_page.dart b/lib/ui/screens/chat/chat_page.dart index d4370b4..6c89c8d 100644 --- a/lib/ui/screens/chat/chat_page.dart +++ b/lib/ui/screens/chat/chat_page.dart @@ -1,4 +1,4 @@ -// ignore_for_file: deprecated_member_use_from_same_package, use_build_context_synchronously, avoid_print +// ignore_for_file: deprecated_member_use_from_same_package, use_build_context_synchronously, avoid_print, deprecated_member_use, curly_braces_in_flow_control_structures import 'dart:math'; @@ -24,6 +24,7 @@ import 'package:hoshan/data/model/ai/messages_model.dart'; import 'package:hoshan/data/model/ai/send_message_model.dart'; import 'package:hoshan/data/model/chat_args.dart'; import 'package:hoshan/data/model/empty_states_enum.dart'; +import 'package:hoshan/data/repository/bot_repository.dart'; import 'package:hoshan/ui/screens/chat/bloc/messages_bloc.dart'; import 'package:hoshan/ui/screens/chat/bloc/related_questions_bloc.dart'; import 'package:hoshan/ui/screens/chat/cubit/receive_message_cubit.dart'; @@ -76,6 +77,22 @@ class _ChatPageState extends State { ValueNotifier maxLines = ValueNotifier(5); late final ValueNotifier selectedBotId = ValueNotifier(widget.chatArgs.bot.id ?? 1); + final ValueNotifier isModelSelectionEnabled = ValueNotifier(true); + late final ValueNotifier currentCost = + ValueNotifier(widget.chatArgs.bot.cost ?? 1); + + Future _updateCostFromApi(int botId) async { + try { + final botData = await BotRepository.getSingleBot(id: botId); + if (botData.cost != null) { + currentCost.value = botData.cost!; + } + } catch (e) { + if (kDebugMode) { + print('Error fetching bot cost: $e'); + } + } + } void sendRequest( {required final String? message, @@ -1292,6 +1309,7 @@ class _ChatPageState extends State { }, listener: (context, state) { if (state is ReceiveMessageDone) { + isModelSelectionEnabled.value = false; context.read().add(AddMessage(message: state.message)); if (state.model.chatId != null) { if (chatId == null && !isGhost.value) { @@ -1708,26 +1726,55 @@ class _ChatPageState extends State { ) ], ), - Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.secondary, - borderRadius: BorderRadius.circular(12)), - child: Row( - children: [ - Text( - bot.cost == 0 || bot.cost == null - ? 'رایگان' - : bot.cost.toString(), - style: AppTextStyles.body3.copyWith(color: Colors.white), + ValueListenableBuilder( + valueListenable: currentCost, + builder: (context, cost, _) { + return TweenAnimationBuilder( + duration: const Duration(milliseconds: 400), + curve: Curves.easeInOut, + tween: Tween( + begin: cost.toDouble(), + end: cost.toDouble(), ), - const SizedBox( - width: 4, - ), - Assets.icon.outline.coin - .svg(color: Colors.white, width: 18, height: 18) - ], - ), + builder: (context, value, child) { + return Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.secondary, + borderRadius: BorderRadius.circular(12)), + child: Row( + children: [ + AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + transitionBuilder: + (Widget child, Animation animation) { + return ScaleTransition( + scale: animation, + child: FadeTransition( + opacity: animation, + child: child, + ), + ); + }, + child: Text( + cost == 0 ? 'رایگان' : cost.toString(), + key: ValueKey(cost), + style: AppTextStyles.body3 + .copyWith(color: Colors.white), + ), + ), + const SizedBox( + width: 4, + ), + Assets.icon.outline.coin + .svg(color: Colors.white, width: 18, height: 18) + ], + ), + ); + }, + ); + }, ), ], ), @@ -1874,7 +1921,6 @@ class _ChatPageState extends State { child: TextField( controller: messageText, onChanged: (value) {}, - enabled: (bot.deleted != null && !bot @@ -1896,7 +1942,7 @@ class _ChatPageState extends State { .attachment != 3), minLines: 1, - maxLines: 6, // Set this + maxLines: 6, keyboardType: TextInputType .multiline, @@ -2062,107 +2108,142 @@ class _ChatPageState extends State { children: [ if (bot.tool == null || !bot.tool!) ValueListenableBuilder( - valueListenable: selectedBotId, - builder: (context, currentBotId, _) { - String botName = currentBotId == 1 - ? 'ChatGPT' - : currentBotId == 2 - ? 'Gemini' - : currentBotId == 4 - ? 'Grok' - : 'Claude'; + valueListenable: isModelSelectionEnabled, + builder: (context, isEnabled, _) { + return ValueListenableBuilder( + valueListenable: selectedBotId, + builder: (context, currentBotId, _) { + String botName = currentBotId == 1 + ? 'ChatGPT' + : currentBotId == 2 + ? 'Gemini' + : currentBotId == 4 + ? 'Grok' + : 'Claude'; - return PopupMenuButton( - color: - Theme.of(context).colorScheme.surface, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - offset: const Offset(0, -10), - onSelected: (int value) { - print('🤖 Bot selected: $value'); - selectedBotId.value = value; - }, - itemBuilder: (BuildContext context) => - >[ - PopupMenuItem( - value: 1, - child: Text( - 'ChatGPT', - style: AppTextStyles.body5.copyWith( - fontWeight: currentBotId == 1 - ? FontWeight.bold - : FontWeight.normal, - ), - ), - ), - PopupMenuItem( - value: 2, - child: Text( - 'Gemini', - style: AppTextStyles.body5.copyWith( - fontWeight: currentBotId == 2 - ? FontWeight.bold - : FontWeight.normal, - ), - ), - ), - PopupMenuItem( - value: 4, - child: Text( - 'Grok', - style: AppTextStyles.body5.copyWith( - fontWeight: currentBotId == 4 - ? FontWeight.bold - : FontWeight.normal, - ), - ), - ), - PopupMenuItem( - value: 9, - child: Text( - 'Claude', - style: AppTextStyles.body5.copyWith( - fontWeight: currentBotId == 9 - ? FontWeight.bold - : FontWeight.normal, - ), - ), - ), - ], - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .primary - .withOpacity(0.1), - borderRadius: BorderRadius.circular(8), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - botName, - style: AppTextStyles.body6.copyWith( - color: Theme.of(context) - .colorScheme - .primary, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(width: 4), - Icon( - Icons.keyboard_arrow_up, - size: 16, + return IgnorePointer( + ignoring: !isEnabled, + child: Opacity( + opacity: isEnabled ? 1.0 : 0.5, + child: PopupMenuButton( color: Theme.of(context) .colorScheme - .primary, + .surface, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(12), + ), + offset: const Offset(0, -10), + onSelected: (int value) { + print('🤖 Bot selected: $value'); + selectedBotId.value = value; + _updateCostFromApi(value); + }, + itemBuilder: + (BuildContext context) => + >[ + PopupMenuItem( + value: 1, + child: Text( + 'ChatGPT', + style: AppTextStyles.body5 + .copyWith( + fontWeight: + currentBotId == 1 + ? FontWeight.bold + : FontWeight.normal, + ), + ), + ), + PopupMenuItem( + value: 2, + child: Text( + 'Gemini', + style: AppTextStyles.body5 + .copyWith( + fontWeight: + currentBotId == 2 + ? FontWeight.bold + : FontWeight.normal, + ), + ), + ), + PopupMenuItem( + value: 4, + child: Text( + 'Grok', + style: AppTextStyles.body5 + .copyWith( + fontWeight: + currentBotId == 4 + ? FontWeight.bold + : FontWeight.normal, + ), + ), + ), + PopupMenuItem( + value: 9, + child: Text( + 'Claude', + style: AppTextStyles.body5 + .copyWith( + fontWeight: + currentBotId == 9 + ? FontWeight.bold + : FontWeight.normal, + ), + ), + ), + ], + child: Container( + padding: + const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4), + decoration: BoxDecoration( + color: Theme.of(context) + .colorScheme + .primary + .withOpacity( + isEnabled ? 0.1 : 0.05), + borderRadius: + BorderRadius.circular(8), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + botName, + style: AppTextStyles.body6 + .copyWith( + color: Theme.of(context) + .colorScheme + .primary + .withOpacity(isEnabled + ? 1.0 + : 0.5), + fontWeight: + FontWeight.bold, + ), + ), + const SizedBox(width: 4), + Icon( + Icons.keyboard_arrow_up, + size: 16, + color: Theme.of(context) + .colorScheme + .primary + .withOpacity(isEnabled + ? 1.0 + : 0.5), + ), + ], + ), + ), ), - ], - ), - ), + ), + ); + }, ); }, ), @@ -2240,100 +2321,71 @@ class _ChatPageState extends State { const SizedBox( width: 12, ), - if ((bot.deleted != null && !bot.deleted!)) - if (bot.attachmentType != null && - bot.attachmentType!.isNotEmpty) - ValueListenableBuilder( - valueListenable: visibleAttach, - builder: (context, value, child) { - return AnimatedVisibility( - isVisible: value, - duration: - const Duration(milliseconds: 300), - fadeMode: FadeMode.horizontal, - child: Padding( - padding: - const EdgeInsets.only(left: 12.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment.end, - children: [ - if (bot.attachmentType! - .contains('image')) - Padding( - padding: - const EdgeInsets.only( - right: 8.0), - child: CircleIconBtn( - icon: Assets.icon.outline - .galleryAdd, - color: Theme.of(context) - .colorScheme - .primary, - iconColor: Colors.white, - onTap: () async { - await BottomSheetHandler( - context) - .showPickImage( - onSelect: (file) { - selectedFile.value = - file; - if (widget - .chatArgs - .bot - .attachment != - 3) { - visibleAttach - .value = - false; - } - }, - ); - }), - ), - if (bot.attachmentType! - .contains('audio')) - Padding( - padding: - const EdgeInsets.only( - right: 8.0), - child: CircleIconBtn( - icon: Assets - .icon.outline.musicnote, - color: Theme.of(context) - .colorScheme - .primary, - iconColor: Colors.white, - onTap: () async { - final file = - await PickFileService( + ValueListenableBuilder( + valueListenable: selectedBotId, + builder: (context, currentBotId, child) { + // غیرفعال کردن قابلیت ارسال عکس برای بات با id=4 (Grok) + if ((bot.deleted != null && !bot.deleted!) && + currentBotId != 4) if (bot.attachmentType != + null && + bot.attachmentType!.isNotEmpty) + return ValueListenableBuilder( + valueListenable: visibleAttach, + builder: (context, value, child) { + return AnimatedVisibility( + isVisible: value, + duration: + const Duration(milliseconds: 300), + fadeMode: FadeMode.horizontal, + child: Padding( + padding: const EdgeInsets.only( + left: 12.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.end, + children: [ + if (bot.attachmentType! + .contains('image')) + Padding( + padding: + const EdgeInsets.only( + right: 8.0), + child: CircleIconBtn( + icon: Assets.icon + .outline.galleryAdd, + color: Theme.of(context) + .colorScheme + .primary, + iconColor: Colors.white, + onTap: () async { + await BottomSheetHandler( context) - .getFile( - fileType: - FileType - .audio); - if (file != null) { - selectedFile.value = - file.single; - if (widget.chatArgs.bot - .attachment != - 3) { - visibleAttach.value = - false; - } - } - }, + .showPickImage( + onSelect: (file) { + selectedFile + .value = file; + if (widget + .chatArgs + .bot + .attachment != + 3) { + visibleAttach + .value = + false; + } + }, + ); + }), ), - ), - if (bot.attachmentType! - .contains('pdf')) - Padding( - padding: - const EdgeInsets.only( - right: 8.0), - child: CircleIconBtn( + if (bot.attachmentType! + .contains('audio')) + Padding( + padding: + const EdgeInsets.only( + right: 8.0), + child: CircleIconBtn( icon: Assets.icon.outline - .folderAdd, + .musicnote, color: Theme.of(context) .colorScheme .primary, @@ -2345,19 +2397,7 @@ class _ChatPageState extends State { .getFile( fileType: FileType - .custom, - allowedExtensions: [ - 'pdf', - 'doc', - 'docx', - 'xls', - 'xlsx', - 'xlsm', - 'xlsb', - 'xlt', - 'xltx', - 'xltm' - ]); + .audio); if (file != null) { selectedFile.value = file.single; @@ -2370,31 +2410,91 @@ class _ChatPageState extends State { .value = false; } } - }), - ) - ], - ), - )); - }, - ), - if ((bot.deleted != null && !bot.deleted!)) - if (bot.attachment != 0 && - bot.attachmentType != null && - bot.attachmentType!.isNotEmpty && - bot.attachment != 3) - GestureDetector( - onTap: () { - if (widget.chatArgs.bot.attachment != 3) { - visibleAttach.value = - !visibleAttach.value; - } + }, + ), + ), + if (bot.attachmentType! + .contains('pdf')) + Padding( + padding: + const EdgeInsets.only( + right: 8.0), + child: CircleIconBtn( + icon: Assets.icon + .outline.folderAdd, + color: Theme.of(context) + .colorScheme + .primary, + iconColor: Colors.white, + onTap: () async { + final file = await PickFileService( + context) + .getFile( + fileType: + FileType + .custom, + allowedExtensions: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'xlsm', + 'xlsb', + 'xlt', + 'xltx', + 'xltm' + ]); + if (file != null) { + selectedFile.value = + file.single; + if (widget + .chatArgs + .bot + .attachment != + 3) { + visibleAttach + .value = + false; + } + } + }), + ) + ], + ), + )); }, - child: Assets.icon.outline.elementPlus.svg( - width: 24, - height: 24, - color: Theme.of(context) - .colorScheme - .primary)), + ); + return const SizedBox.shrink(); + }, + ), + ValueListenableBuilder( + valueListenable: selectedBotId, + builder: (context, currentBotId, child) { + if ((bot.deleted != null && !bot.deleted!) && + currentBotId != 4) if (bot.attachment != + 0 && + bot.attachmentType != null && + bot.attachmentType!.isNotEmpty && + bot.attachment != 3) + return GestureDetector( + onTap: () { + if (widget.chatArgs.bot.attachment != + 3) { + visibleAttach.value = + !visibleAttach.value; + } + }, + child: Assets.icon.outline.elementPlus + .svg( + width: 24, + height: 24, + color: Theme.of(context) + .colorScheme + .primary)); + return const SizedBox.shrink(); + }, + ), ], ), ], diff --git a/lib/ui/screens/family/add_family.dart b/lib/ui/screens/family/add_family.dart index 2f8f7ad..230ba96 100644 --- a/lib/ui/screens/family/add_family.dart +++ b/lib/ui/screens/family/add_family.dart @@ -57,7 +57,9 @@ class _AddFamilyState extends State { final backgroundColor = colorScheme.background; final surfaceColor = colorScheme.surface; final onSurface = colorScheme.onSurface; - final borderColor = const Color.fromARGB(255, 207, 206, 205); + final borderColor = isDark + ? colorScheme.outline.withOpacity(0.5) + : const Color.fromARGB(255, 207, 206, 205); final accent = colorScheme.primary; final success = colorScheme.secondary; @@ -274,6 +276,10 @@ class _AddFamilyState extends State { foregroundColor: onSurface, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), + side: isDark + ? BorderSide( + color: success.withOpacity(0.3)) + : BorderSide.none, ), padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8), @@ -287,6 +293,7 @@ class _AddFamilyState extends State { ? CupertinoIcons.minus : CupertinoIcons.add, size: 18, + color: isDark ? success : null, ), const SizedBox(width: 4), Text( @@ -294,7 +301,7 @@ class _AddFamilyState extends State { ? 'بستن فرم' : 'افزودن عضو جدید', style: AppTextStyles.body5.copyWith( - color: onSurface, + color: isDark ? success : onSurface, fontWeight: FontWeight.bold), ), ], @@ -373,10 +380,13 @@ class _AddFamilyState extends State { padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isDark - ? Color.fromARGB(255, 80, 80, 80) + ? Color.fromARGB(255, 45, 45, 45) : Color.fromARGB(255, 252, 252, 252), borderRadius: BorderRadius.circular(20), - border: Border.all(color: Color.fromARGB(255, 207, 206, 205)), + border: Border.all( + color: isDark + ? colorScheme.outline.withOpacity(0.3) + : Color.fromARGB(255, 207, 206, 205)), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.03), @@ -452,7 +462,7 @@ class _AddFamilyState extends State { // // ], // // ), // ), - const SizedBox(width: 16), + // const SizedBox(width: 16), InkWell( onTap: () { _showDeleteDialog(index); @@ -463,23 +473,7 @@ class _AddFamilyState extends State { height: 25, ), ), - const SizedBox(width: 16), - // Container( - // padding: - // const EdgeInsets.symmetric(horizontal: 15, vertical: 9), - // decoration: BoxDecoration( - // color: Color.fromARGB(255, 224, 236, 255), - // borderRadius: BorderRadius.circular(6), - // ), - // child: Text( - // 'در انتظار تایید', - // style: AppTextStyles.body6.copyWith( - // color: colorScheme.primary, - // fontWeight: FontWeight.bold, - // fontSize: 10, - // ), - // ), - // ), + // const SizedBox(width: 16), ], ), ], @@ -492,6 +486,7 @@ class _AddFamilyState extends State { final TextEditingController editPhoneController = TextEditingController(text: member['phone']); int? editAgeIndex = member['ageIndex']; + final isDark = Theme.of(context).brightness == Brightness.dark; showDialog( context: context, @@ -503,7 +498,9 @@ class _AddFamilyState extends State { insetPadding: const EdgeInsets.symmetric(horizontal: 16), child: Container( decoration: BoxDecoration( - color: const Color.fromARGB(255, 246, 246, 246), + color: isDark + ? Theme.of(context).colorScheme.surface + : const Color.fromARGB(255, 246, 246, 246), borderRadius: BorderRadius.circular(16), border: Border.all(color: AppColors.gray[300]), ), @@ -514,8 +511,10 @@ class _AddFamilyState extends State { width: double.infinity, padding: const EdgeInsets.symmetric( vertical: 12, horizontal: 16), - decoration: const BoxDecoration( - color: Color.fromARGB(255, 224, 236, 255), + decoration: BoxDecoration( + color: isDark + ? Theme.of(context).colorScheme.surfaceVariant + : const Color.fromARGB(255, 224, 236, 255), borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), @@ -528,13 +527,20 @@ class _AddFamilyState extends State { 'ویرایش عضو ${_getOrdinal(index + 1)}', textAlign: TextAlign.right, style: AppTextStyles.body4.copyWith( - color: Colors.black, + color: isDark + ? Theme.of(context) + .colorScheme + .onSurfaceVariant + : Colors.black, fontWeight: FontWeight.bold, ), ), InkWell( onTap: () => Navigator.pop(context), - child: const Icon(CupertinoIcons.clear, size: 20), + child: Icon(CupertinoIcons.clear, + size: 20, + color: + Theme.of(context).colorScheme.onSurface), ) ], ), @@ -542,7 +548,7 @@ class _AddFamilyState extends State { ), Container( height: 2, - color: const Color.fromARGB(255, 30, 29, 27), + color: Theme.of(context).colorScheme.outline, ), Padding( padding: const EdgeInsets.all(16), @@ -563,6 +569,9 @@ class _AddFamilyState extends State { controller: editPhoneController, keyboardType: TextInputType.phone, textDirection: TextDirection.ltr, + style: TextStyle( + color: + Theme.of(context).colorScheme.onSurface), decoration: InputDecoration( suffixIcon: Icon( CupertinoIcons.phone, @@ -693,11 +702,14 @@ class _AddFamilyState extends State { void _showDeleteDialog(int index) { final member = _invitedMembers[index]; + final isDark = Theme.of(context).brightness == Brightness.dark; + showDialog( context: context, builder: (context) { return Dialog( - backgroundColor: Colors.white, + backgroundColor: + isDark ? Theme.of(context).colorScheme.surface : Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), @@ -714,7 +726,9 @@ class _AddFamilyState extends State { InkWell( onTap: () => Navigator.pop(context), child: SvgPicture.asset( - 'assets/icon/outline/close-circle.svg')), + 'assets/icon/outline/close-circle.svg', + color: Theme.of(context).colorScheme.onSurface, + )), ], ), SvgPicture.asset( @@ -727,14 +741,17 @@ class _AddFamilyState extends State { 'کاربر حذف شود؟', style: AppTextStyles.body3.copyWith( fontWeight: FontWeight.bold, - color: Colors.black, + color: Theme.of(context).colorScheme.onSurface, ), ), const SizedBox(height: 8), Text( 'شماره همراه: ${member['phone']}', style: AppTextStyles.body5.copyWith( - color: AppColors.black[700], + color: Theme.of(context) + .colorScheme + .onSurface + .withOpacity(0.7), fontFamily: 'Dana', ), ), @@ -828,8 +845,11 @@ class _AddFamilyState extends State { } }, style: ElevatedButton.styleFrom( - backgroundColor: Colors.grey[200], - foregroundColor: Colors.black, + backgroundColor: isDark + ? Theme.of(context).colorScheme.surfaceVariant + : Colors.grey[200], + foregroundColor: + Theme.of(context).colorScheme.onSurface, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(100), @@ -864,8 +884,11 @@ class _AddFamilyState extends State { required int? groupValue, required ValueChanged onChanged, }) { - final colorScheme = Theme.of(context).colorScheme; + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + final isDark = theme.brightness == Brightness.dark; final isSelected = groupValue == index; + return InkWell( onTap: () => onChanged(index), borderRadius: BorderRadius.circular(8), @@ -873,16 +896,25 @@ class _AddFamilyState extends State { padding: const EdgeInsets.symmetric(vertical: 12), decoration: BoxDecoration( color: isSelected - ? colorScheme.primaryContainer.withOpacity(0.35) - : colorScheme.surfaceVariant, + ? (isDark + ? colorScheme.primary.withOpacity(0.3) + : colorScheme.primaryContainer.withOpacity(0.35)) + : (isDark + ? colorScheme.surfaceVariant + : colorScheme.surfaceVariant), borderRadius: BorderRadius.circular(30), + border: isDark && !isSelected + ? Border.all(color: colorScheme.outline.withOpacity(0.3)) + : null, ), child: Text( title, textAlign: TextAlign.center, style: AppTextStyles.body6.copyWith( color: isSelected - ? colorScheme.onPrimaryContainer + ? (isDark + ? colorScheme.primary + : colorScheme.onPrimaryContainer) : colorScheme.onSurface.withOpacity(0.7), fontWeight: FontWeight.bold, fontSize: 11, @@ -910,10 +942,14 @@ class _AddFamilyState extends State { } Widget _buildInviteCard(int memberNumber) { - final colorScheme = Theme.of(context).colorScheme; + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + final isDark = theme.brightness == Brightness.dark; + return Container( decoration: BoxDecoration( - color: Color.fromARGB(255, 246, 246, 246), + color: + isDark ? colorScheme.surface : Color.fromARGB(255, 246, 246, 246), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( @@ -929,7 +965,9 @@ class _AddFamilyState extends State { width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), decoration: BoxDecoration( - color: Color.fromARGB(255, 224, 236, 255), + color: isDark + ? colorScheme.surfaceVariant + : Color.fromARGB(255, 224, 236, 255), borderRadius: const BorderRadius.vertical(top: Radius.circular(16)), ), @@ -937,7 +975,7 @@ class _AddFamilyState extends State { 'دعوت از عضو ${_getOrdinal(memberNumber)}', textAlign: TextAlign.right, style: AppTextStyles.body4.copyWith( - color: Colors.black, + color: isDark ? colorScheme.onSurfaceVariant : Colors.black, fontWeight: FontWeight.bold, ), ), @@ -963,6 +1001,7 @@ class _AddFamilyState extends State { controller: _phoneController, keyboardType: TextInputType.phone, textDirection: TextDirection.ltr, + style: TextStyle(color: colorScheme.onSurface), decoration: InputDecoration( suffixIcon: Icon( CupertinoIcons.phone, @@ -972,8 +1011,10 @@ class _AddFamilyState extends State { horizontal: 16, vertical: 12), border: OutlineInputBorder( borderRadius: BorderRadius.circular(16), - borderSide: - BorderSide(color: Color.fromARGB(255, 161, 160, 160)), + borderSide: BorderSide( + color: isDark + ? colorScheme.outline.withOpacity(0.5) + : Color.fromARGB(255, 161, 160, 160)), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), @@ -1120,8 +1161,11 @@ class _AddFamilyState extends State { } Widget _buildAgeOption({required String title, required int index}) { - final colorScheme = Theme.of(context).colorScheme; + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + final isDark = theme.brightness == Brightness.dark; final isSelected = _selectedAgeIndex == index; + return InkWell( onTap: () { setState(() { @@ -1133,16 +1177,23 @@ class _AddFamilyState extends State { padding: const EdgeInsets.symmetric(vertical: 12), decoration: BoxDecoration( color: isSelected - ? Color.fromARGB(255, 224, 236, 255) - : Color.fromARGB(255, 233, 232, 231), + ? (isDark + ? colorScheme.primary.withOpacity(0.3) + : Color.fromARGB(255, 224, 236, 255)) + : (isDark + ? colorScheme.surfaceVariant + : Color.fromARGB(255, 233, 232, 231)), borderRadius: BorderRadius.circular(30), + border: isDark && !isSelected + ? Border.all(color: colorScheme.outline.withOpacity(0.3)) + : null, ), child: Text( title, textAlign: TextAlign.center, style: AppTextStyles.body6.copyWith( color: isSelected - ? Colors.black + ? (isDark ? colorScheme.primary : Colors.black) : colorScheme.onSurface.withOpacity(0.7), fontWeight: FontWeight.bold, fontSize: 11, @@ -1155,6 +1206,8 @@ class _AddFamilyState extends State { Widget _buildTopInfoCard(BuildContext context, {required String title, required String icon}) { final colorScheme = Theme.of(context).colorScheme; + final isDark = Theme.of(context).brightness == Brightness.dark; + return Column( children: [ Container( @@ -1163,13 +1216,16 @@ class _AddFamilyState extends State { padding: const EdgeInsets.all(5), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), - color: Color.fromARGB(255, 248, 231, 241), + color: isDark + ? colorScheme.surfaceVariant + : Color.fromARGB(255, 248, 231, 241), ), child: Center( child: SvgPicture.asset( icon, width: 32, height: 32, + color: isDark ? colorScheme.onSurfaceVariant : null, ), ), ), diff --git a/lib/ui/screens/gmedia/chats/video_chat_page.dart b/lib/ui/screens/gmedia/chats/video_chat_page.dart index 4016a96..bea99d7 100644 --- a/lib/ui/screens/gmedia/chats/video_chat_page.dart +++ b/lib/ui/screens/gmedia/chats/video_chat_page.dart @@ -259,7 +259,6 @@ class _TtaPageState extends State { } final m = mState.messages; List> allMessages = groupMessages(m); - // فیلتر کردن گروه‌هایی که حداقل یک پیام با video_url دارند List> messages = allMessages.where((group) { return group.any((msg) => msg.content?.any((c) => c.videoUrl != null) ?? false);