diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 15273e9fb..d3ac2306b 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -482,7 +482,7 @@ class Message extends StatelessWidget { miniIcon: user.id == BotName.byEnvironment ? BotSettingsLanguageIcon( - room: controller.room, + user: user, ) : null, presenceOffset: diff --git a/lib/pangea/activity_sessions/activity_participant_indicator.dart b/lib/pangea/activity_sessions/activity_participant_indicator.dart index 0f85ff327..58fd0403f 100644 --- a/lib/pangea/activity_sessions/activity_participant_indicator.dart +++ b/lib/pangea/activity_sessions/activity_participant_indicator.dart @@ -72,7 +72,7 @@ class ActivityParticipantIndicator extends StatelessWidget { userId: userId, miniIcon: room != null && userId == BotName.byEnvironment - ? BotSettingsLanguageIcon(room: room!) + ? BotSettingsLanguageIcon(user: user!) : null, presenceOffset: room != null && userId == BotName.byEnvironment diff --git a/lib/pangea/bot/widgets/bot_chat_settings_dialog.dart b/lib/pangea/bot/widgets/bot_chat_settings_dialog.dart index 663b1f217..87c603de2 100644 --- a/lib/pangea/bot/widgets/bot_chat_settings_dialog.dart +++ b/lib/pangea/bot/widgets/bot_chat_settings_dialog.dart @@ -9,34 +9,17 @@ import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart import 'package:fluffychat/pangea/bot/utils/bot_room_extension.dart'; import 'package:fluffychat/pangea/chat_settings/models/bot_options_model.dart'; import 'package:fluffychat/pangea/chat_settings/widgets/language_level_dropdown.dart'; +import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/common/widgets/dropdown_text_button.dart'; import 'package:fluffychat/pangea/languages/language_model.dart'; import 'package:fluffychat/pangea/languages/p_language_store.dart'; import 'package:fluffychat/pangea/learning_settings/language_level_type_enum.dart'; import 'package:fluffychat/pangea/learning_settings/p_language_dropdown.dart'; -import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart'; -import 'package:fluffychat/widgets/future_loading_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; class BotChatSettingsDialog extends StatefulWidget { final Room room; - static Future show({ - required BuildContext context, - required Room room, - }) async { - final resp = await showAdaptiveDialog( - context: context, - barrierDismissible: true, - builder: (context) => BotChatSettingsDialog(room: room), - ); - if (resp == null) return; - await showFutureLoadingDialog( - context: context, - future: () => room.setBotOptions(resp), - ); - } - const BotChatSettingsDialog({ required this.room, super.key, @@ -68,125 +51,143 @@ class BotChatSettingsDialogState extends State { bool get _isActivity => widget.room.isActivitySession; - void _setLanguage(LanguageModel? lang) => - setState(() => _selectedLang = lang); - void _setLevel(LanguageLevelTypeEnum? level) => - setState(() => _selectedLevel = level); - void _setVoice(String? voice) => setState(() => _selectedVoice = voice); + Future _setLanguage(LanguageModel? lang) async { + setState(() { + _selectedLang = lang; + _selectedVoice = null; + }); - BotOptionsModel get _updatedModel { - final botSettings = widget.room.botOptions ?? BotOptionsModel(); - if (_selectedLang != null) { - botSettings.targetLanguage = _selectedLang!.langCode; + final model = widget.room.botOptions ?? BotOptionsModel(); + model.targetLanguage = lang?.langCode; + model.targetVoice = null; + + try { + await widget.room.setBotOptions(model); + } catch (e, s) { + ErrorHandler.logError( + e: e, + s: s, + data: { + 'roomId': widget.room.id, + 'langCode': lang?.langCode, + }, + ); } - if (_selectedLevel != null) { - botSettings.languageLevel = _selectedLevel!; + } + + Future _setLevel(LanguageLevelTypeEnum? level) async { + if (level == null) return; + + setState(() => _selectedLevel = level); + final model = widget.room.botOptions ?? BotOptionsModel(); + model.languageLevel = level; + try { + await widget.room.setBotOptions(model); + } catch (e, s) { + ErrorHandler.logError( + e: e, + s: s, + data: { + 'roomId': widget.room.id, + 'level': level.name, + }, + ); } - if (_selectedVoice != null) { - botSettings.targetVoice = _selectedVoice; + } + + Future _setVoice(String? voice) async { + setState(() => _selectedVoice = voice); + final model = widget.room.botOptions ?? BotOptionsModel(); + model.targetVoice = voice; + try { + await widget.room.setBotOptions(model); + } catch (e, s) { + ErrorHandler.logError( + e: e, + s: s, + data: { + 'roomId': widget.room.id, + 'voice': voice, + }, + ); } - return botSettings; } @override Widget build(BuildContext context) { - return AlertDialog.adaptive( - title: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 256), - child: Center( - child: Text( - L10n.of(context).botSettings, - textAlign: TextAlign.center, + return Material( + type: MaterialType.transparency, + child: Column( + spacing: 12.0, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (widget.room.isActivitySession) + ListTile( + contentPadding: const EdgeInsets.all(0.0), + minLeadingWidth: 12.0, + leading: Icon( + Icons.info_outline, + size: 12.0, + color: Theme.of(context).disabledColor, + ), + title: Text( + L10n.of(context).activitySettingsOverrideWarning, + style: TextStyle( + color: Theme.of(context).disabledColor, + fontSize: 12.0, + ), + ), + ) + else + const SizedBox(), + PLanguageDropdown( + onChange: _setLanguage, + initialLanguage: _selectedLang, + languages: + MatrixState.pangeaController.pLanguageStore.targetOptions, + isL2List: true, + decorationText: L10n.of(context).targetLanguage, + enabled: !widget.room.isActivitySession, ), - ), - ), - content: Material( - type: MaterialType.transparency, - child: Container( - padding: const EdgeInsets.only(top: 16.0), - constraints: const BoxConstraints( - maxWidth: 256, - maxHeight: 300, + LanguageLevelDropdown( + initialLevel: _selectedLevel, + onChanged: _setLevel, + enabled: !widget.room.isActivitySession, ), - child: SingleChildScrollView( - child: Column( - spacing: 16.0, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (_isActivity) - ListTile( - contentPadding: const EdgeInsets.all(0.0), - minLeadingWidth: 12.0, - leading: Icon( - Icons.info_outline, - size: 12.0, - color: Theme.of(context).disabledColor, - ), - title: Text( - L10n.of(context).activitySettingsOverrideWarning, - style: TextStyle( - color: Theme.of(context).disabledColor, - fontSize: 12.0, - ), - ), - ), - PLanguageDropdown( - onChange: _setLanguage, - initialLanguage: _selectedLang, - languages: - MatrixState.pangeaController.pLanguageStore.targetOptions, - isL2List: true, - decorationText: L10n.of(context).targetLanguage, - enabled: !_isActivity, - ), - LanguageLevelDropdown( - initialLevel: _selectedLevel, - onChanged: _setLevel, - enabled: !_isActivity, - ), - DropdownButtonFormField2( - customButton: _selectedVoice != null - ? CustomDropdownTextButton(text: _selectedVoice!) - : null, - menuItemStyleData: const MenuItemStyleData( - padding: EdgeInsets.symmetric( - vertical: 8.0, - horizontal: 16.0, - ), - ), - decoration: InputDecoration( - labelText: L10n.of(context).voice, - ), - isExpanded: true, - dropdownStyleData: DropdownStyleData( - maxHeight: kIsWeb ? 250 : null, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainerHigh, - borderRadius: BorderRadius.circular(14.0), - ), - ), - items: (_selectedLang?.voices ?? []).map((voice) { - return DropdownMenuItem( - value: voice, - child: Text(voice), - ); - }).toList(), - onChanged: _setVoice, - value: _selectedVoice, - ), - ], + DropdownButtonFormField2( + customButton: _selectedVoice != null + ? CustomDropdownTextButton(text: _selectedVoice!) + : null, + menuItemStyleData: const MenuItemStyleData( + padding: EdgeInsets.symmetric( + vertical: 8.0, + horizontal: 16.0, + ), ), + decoration: InputDecoration( + labelText: L10n.of(context).voice, + ), + isExpanded: true, + dropdownStyleData: DropdownStyleData( + maxHeight: kIsWeb ? 250 : null, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceContainerHigh, + borderRadius: BorderRadius.circular(14.0), + ), + ), + items: (_selectedLang?.voices ?? []).map((voice) { + return DropdownMenuItem( + value: voice, + child: Text(voice), + ); + }).toList(), + onChanged: _setVoice, + value: _selectedVoice, ), - ), + const SizedBox(), + ], ), - actions: [ - AdaptiveDialogAction( - bigButtons: true, - onPressed: () => Navigator.of(context).pop(_updatedModel), - child: Text(L10n.of(context).submit), - ), - ], ); } } diff --git a/lib/pangea/bot/widgets/bot_settings_language_icon.dart b/lib/pangea/bot/widgets/bot_settings_language_icon.dart index 7a922454b..837bba59f 100644 --- a/lib/pangea/bot/widgets/bot_settings_language_icon.dart +++ b/lib/pangea/bot/widgets/bot_settings_language_icon.dart @@ -4,19 +4,20 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart'; import 'package:fluffychat/pangea/bot/utils/bot_room_extension.dart'; -import 'package:fluffychat/pangea/bot/widgets/bot_chat_settings_dialog.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart'; class BotSettingsLanguageIcon extends StatelessWidget { - final Room room; + final User user; const BotSettingsLanguageIcon({ super.key, - required this.room, + required this.user, }); @override Widget build(BuildContext context) { + final room = user.room; String? langCode = room.botOptions?.targetLanguage; if (room.isActivitySession && room.activityPlan != null) { langCode = room.activityPlan!.req.targetLanguage; @@ -29,8 +30,9 @@ class BotSettingsLanguageIcon extends StatelessWidget { return InkWell( borderRadius: BorderRadius.circular(32.0), onTap: room.isRoomAdmin - ? () => BotChatSettingsDialog.show( + ? () => showMemberActionsPopupMenu( context: context, + user: user, room: room, ) : null, diff --git a/lib/pangea/languages/p_language_store.dart b/lib/pangea/languages/p_language_store.dart index 02c238b88..60327881b 100644 --- a/lib/pangea/languages/p_language_store.dart +++ b/lib/pangea/languages/p_language_store.dart @@ -49,17 +49,17 @@ class PLanguageStore { : LanguageConstants.languageList .map((e) => LanguageModel.fromJson(e)) .toList(); + + await _MyShared.saveJson(PrefKey.languagesKey, { + PrefKey.languagesKey: _langList.map((e) => e.toJson()).toList(), + }); + + await _MyShared.saveString( + PrefKey.lastFetched, + DateTime.now().toIso8601String(), + ); } - await _MyShared.saveJson(PrefKey.languagesKey, { - PrefKey.languagesKey: _langList.map((e) => e.toJson()).toList(), - }); - - await _MyShared.saveString( - PrefKey.lastFetched, - DateTime.now().toIso8601String(), - ); - _langList.removeWhere( (element) => element.langCode == LanguageKeys.unknownLanguage, ); @@ -78,7 +78,7 @@ class PLanguageStore { return true; } - final DateTime targetDate = DateTime(2026, 1, 9); + final DateTime targetDate = DateTime(2026, 1, 15); if (lastFetchedDate.isBefore(targetDate)) { return true; } diff --git a/lib/widgets/member_actions_popup_menu_button.dart b/lib/widgets/member_actions_popup_menu_button.dart index 5c444dead..75376e351 100644 --- a/lib/widgets/member_actions_popup_menu_button.dart +++ b/lib/widgets/member_actions_popup_menu_button.dart @@ -59,6 +59,7 @@ void showMemberActionsPopupMenu({ PopupMenuItem( value: _MemberActions.info, child: Row( + // Pangea# spacing: 12.0, children: [ Avatar( @@ -107,6 +108,15 @@ void showMemberActionsPopupMenu({ ], ), ), + if (user.id == BotName.byEnvironment && room != null && room.isRoomAdmin) + PopupMenuItem( + enabled: false, + padding: const EdgeInsets.only( + left: 12.0, + right: 12.0, + ), + child: BotChatSettingsDialog(room: room), + ), const PopupMenuDivider(), // #Pangea if (user.room.client.userID != user.id) @@ -124,17 +134,6 @@ void showMemberActionsPopupMenu({ ], ), ), - if (user.id == BotName.byEnvironment && room != null && room.isRoomAdmin) - PopupMenuItem( - value: _MemberActions.botSettings, - child: Row( - children: [ - const Icon(Icons.settings_outlined), - const SizedBox(width: 18), - Text(L10n.of(context).botSettings), - ], - ), - ), // Pangea# if (onMention != null) PopupMenuItem( @@ -356,12 +355,6 @@ void showMemberActionsPopupMenu({ final roomId = roomIdResult.result; if (roomId == null) return; router.go('/rooms/$roomId'); - case _MemberActions.botSettings: - await BotChatSettingsDialog.show( - context: context, - room: room!, - ); - return; // Pangea# case _MemberActions.info: await UserDialog.show( @@ -401,6 +394,5 @@ enum _MemberActions { // #Pangea // report, chat, - botSettings, // Pangea# } diff --git a/pubspec.yaml b/pubspec.yaml index 77f4dbc51..0e30c0b85 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,7 +6,7 @@ description: Learn a language while texting your friends. # Pangea# publish_to: none # On version bump also increase the build number for F-Droid -version: 4.1.16+1 +version: 4.1.16+2 environment: sdk: ">=3.0.0 <4.0.0"