feat: move language dropdowns into learning settings dialog (#1695)

pull/1593/head
ggurdin 9 months ago committed by GitHub
parent 75a0d1e07b
commit 1e40e1d1a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -4,11 +4,14 @@ import 'package:country_picker/country_picker.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart'; import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart';
import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'package:fluffychat/pangea/learning_settings/pages/settings_learning_view.dart'; import 'package:fluffychat/pangea/learning_settings/pages/settings_learning_view.dart';
import 'package:fluffychat/pangea/learning_settings/utils/language_list_util.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/p_language_dialog.dart'; import 'package:fluffychat/pangea/learning_settings/widgets/p_language_dialog.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart'; import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart'; import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart';
import 'package:fluffychat/pangea/user/models/user_model.dart'; import 'package:fluffychat/pangea/user/models/user_model.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
class SettingsLearning extends StatefulWidget { class SettingsLearning extends StatefulWidget {
@ -22,6 +25,22 @@ class SettingsLearningController extends State<SettingsLearning> {
PangeaController pangeaController = MatrixState.pangeaController; PangeaController pangeaController = MatrixState.pangeaController;
final tts = TtsController(); final tts = TtsController();
LanguageModel? get selectedSourceLanguage {
return userL1 ?? pangeaController.languageController.systemLanguage;
}
LanguageModel? get selectedTargetLanguage {
return userL2 ??
((selectedSourceLanguage?.langCode != 'en')
? PangeaLanguage.byLangCode('en')!
: PangeaLanguage.byLangCode('es')!);
}
LanguageModel? get userL1 => pangeaController.languageController.userL1;
LanguageModel? get userL2 => pangeaController.languageController.userL2;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -34,6 +53,33 @@ class SettingsLearningController extends State<SettingsLearning> {
super.dispose(); super.dispose();
} }
Future<void> setSelectedLanguage({
LanguageModel? sourceLanguage,
LanguageModel? targetLanguage,
}) async {
if (targetLanguage == null && sourceLanguage == null) return;
if (!formKey.currentState!.validate()) return;
await showFutureLoadingDialog(
context: context,
future: () async {
pangeaController.userController.updateProfile(
(profile) {
if (sourceLanguage != null) {
profile.userSettings.sourceLanguage = sourceLanguage.langCode;
}
if (targetLanguage != null) {
profile.userSettings.targetLanguage = targetLanguage.langCode;
}
return profile;
},
waitForDataInSync: true,
);
},
);
if (mounted) setState(() {});
}
void setPublicProfile(bool isPublic) { void setPublicProfile(bool isPublic) {
pangeaController.userController.updateProfile( pangeaController.userController.updateProfile(
(profile) { (profile) {

@ -8,9 +8,10 @@ import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/chat_settings/widgets/language_level_dropdown.dart'; import 'package:fluffychat/pangea/chat_settings/widgets/language_level_dropdown.dart';
import 'package:fluffychat/pangea/common/constants/model_keys.dart'; import 'package:fluffychat/pangea/common/constants/model_keys.dart';
import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart'; import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart';
import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'package:fluffychat/pangea/learning_settings/pages/settings_learning.dart'; import 'package:fluffychat/pangea/learning_settings/pages/settings_learning.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/country_picker_tile.dart'; import 'package:fluffychat/pangea/learning_settings/widgets/country_picker_tile.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/language_tile.dart'; import 'package:fluffychat/pangea/learning_settings/widgets/p_language_dropdown.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/p_settings_switch_list_tile.dart'; import 'package:fluffychat/pangea/learning_settings/widgets/p_settings_switch_list_tile.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart'; import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/platform_infos.dart';
@ -46,88 +47,126 @@ class SettingsLearningView extends StatelessWidget {
iconColor: Theme.of(context).textTheme.bodyLarge!.color, iconColor: Theme.of(context).textTheme.bodyLarge!.color,
child: MaxWidthBody( child: MaxWidthBody(
withScrolling: true, withScrolling: true,
child: Column( child: Form(
children: [ key: controller.formKey,
LanguageTile(controller), child: Column(
CountryPickerTile(controller), children: [
Padding( const SizedBox(height: 8.0),
padding: const EdgeInsets.only(top: 16.0, bottom: 24.0), PLanguageDropdown(
child: LanguageLevelDropdown( onChange: (lang) =>
initialLevel: controller.cefrLevel, controller.setSelectedLanguage(sourceLanguage: lang),
onChanged: controller.setCefrLevel, initialLanguage: controller.selectedSourceLanguage ??
LanguageModel.unknown,
languages: MatrixState
.pangeaController.pLanguageStore.baseOptions,
isL2List: false,
decorationText: L10n.of(context).myBaseLanguage,
validator: (lang) {
if (lang == controller.selectedTargetLanguage) {
return L10n.of(context).noIdenticalLanguages;
}
return null;
},
), ),
), const SizedBox(height: 24.0),
const Divider(height: 1), PLanguageDropdown(
ListTile( onChange: (lang) =>
title: Text(L10n.of(context).toggleToolSettingsDescription), controller.setSelectedLanguage(targetLanguage: lang),
), initialLanguage: controller.selectedTargetLanguage,
for (final toolSetting in ToolSetting.values languages: MatrixState
.where((tool) => tool.isAvailableSetting)) .pangeaController.pLanguageStore.targetOptions,
Column( isL2List: true,
children: [ decorationText: L10n.of(context).iWantToLearn,
ProfileSettingsSwitchListTile.adaptive( validator: (lang) {
defaultValue: controller.getToolSetting(toolSetting), if (lang == controller.selectedSourceLanguage) {
title: toolSetting.toolName(context), return L10n.of(context).noIdenticalLanguages;
subtitle: toolSetting == ToolSetting.enableTTS && }
!controller.tts.isLanguageFullySupported return null;
? null },
: toolSetting.toolDescription(context), ),
onChange: (bool value) => const SizedBox(height: 16.0),
controller.updateToolSetting( CountryPickerTile(controller),
toolSetting, Padding(
value, padding: const EdgeInsets.only(top: 16.0, bottom: 24.0),
), child: LanguageLevelDropdown(
enabled: toolSetting == ToolSetting.enableTTS initialLevel: controller.cefrLevel,
? controller.tts.isLanguageFullySupported onChanged: controller.setCefrLevel,
: true, ),
), ),
if (toolSetting == ToolSetting.enableTTS && const Divider(height: 1),
!controller.tts.isLanguageFullySupported) ListTile(
ListTile( title:
trailing: const Padding( Text(L10n.of(context).toggleToolSettingsDescription),
padding: EdgeInsets.symmetric(horizontal: 16.0), ),
child: Icon(Icons.info_outlined), for (final toolSetting in ToolSetting.values
.where((tool) => tool.isAvailableSetting))
Column(
children: [
ProfileSettingsSwitchListTile.adaptive(
defaultValue:
controller.getToolSetting(toolSetting),
title: toolSetting.toolName(context),
subtitle: toolSetting == ToolSetting.enableTTS &&
!controller.tts.isLanguageFullySupported
? null
: toolSetting.toolDescription(context),
onChange: (bool value) =>
controller.updateToolSetting(
toolSetting,
value,
), ),
subtitle: RichText( enabled: toolSetting == ToolSetting.enableTTS
text: TextSpan( ? controller.tts.isLanguageFullySupported
text: L10n.of(context).couldNotFindTTS, : true,
style: DefaultTextStyle.of(context).style, ),
children: [ if (toolSetting == ToolSetting.enableTTS &&
if (PlatformInfos.isWindows || !controller.tts.isLanguageFullySupported)
PlatformInfos.isAndroid) ListTile(
TextSpan( trailing: const Padding(
text: L10n.of(context) padding: EdgeInsets.symmetric(horizontal: 16.0),
.ttsInstructionsHyperlink, child: Icon(Icons.info_outlined),
style: const TextStyle( ),
color: Colors.blue, subtitle: RichText(
fontWeight: FontWeight.bold, text: TextSpan(
decoration: TextDecoration.underline, text: L10n.of(context).couldNotFindTTS,
style: DefaultTextStyle.of(context).style,
children: [
if (PlatformInfos.isWindows ||
PlatformInfos.isAndroid)
TextSpan(
text: L10n.of(context)
.ttsInstructionsHyperlink,
style: const TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()
..onTap = () {
launchUrlString(
PlatformInfos.isWindows
? AppConfig
.windowsTTSDownloadInstructions
: AppConfig
.androidTTSDownloadInstructions,
);
},
), ),
recognizer: TapGestureRecognizer() ],
..onTap = () { ),
launchUrlString(
PlatformInfos.isWindows
? AppConfig
.windowsTTSDownloadInstructions
: AppConfig
.androidTTSDownloadInstructions,
);
},
),
],
), ),
), ),
), ],
], ),
SwitchListTile.adaptive(
value: controller.publicProfile,
onChanged: controller.setPublicProfile,
title: Text(L10n.of(context).publicProfileTitle),
subtitle: Text(L10n.of(context).publicProfileDesc),
activeColor: AppConfig.activeToggleColor,
), ),
SwitchListTile.adaptive( ],
value: controller.publicProfile, ),
onChanged: controller.setPublicProfile,
title: Text(L10n.of(context).publicProfileTitle),
subtitle: Text(L10n.of(context).publicProfileDesc),
activeColor: AppConfig.activeToggleColor,
),
],
), ),
), ),
), ),

@ -2,14 +2,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pangea/learning_settings/enums/l2_support_enum.dart'; import 'package:fluffychat/pangea/learning_settings/enums/l2_support_enum.dart';
import 'package:fluffychat/pangea/learning_settings/models/language_model.dart'; import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'flag.dart'; import 'flag.dart';
class PLanguageDropdown extends StatefulWidget { class PLanguageDropdown extends StatelessWidget {
final List<LanguageModel> languages; final List<LanguageModel> languages;
final LanguageModel? initialLanguage; final LanguageModel? initialLanguage;
final Function(LanguageModel) onChange; final Function(LanguageModel) onChange;
@ -17,6 +15,7 @@ class PLanguageDropdown extends StatefulWidget {
final bool isL2List; final bool isL2List;
final String decorationText; final String decorationText;
final String? error; final String? error;
final String? Function(LanguageModel?)? validator;
const PLanguageDropdown({ const PLanguageDropdown({
super.key, super.key,
@ -27,16 +26,12 @@ class PLanguageDropdown extends StatefulWidget {
required this.decorationText, required this.decorationText,
this.isL2List = false, this.isL2List = false,
this.error, this.error,
this.validator,
}); });
@override
State<PLanguageDropdown> createState() => _PLanguageDropdownState();
}
class _PLanguageDropdownState extends State<PLanguageDropdown> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<LanguageModel> sortedLanguages = widget.languages; final List<LanguageModel> sortedLanguages = languages;
final String systemLang = Localizations.localeOf(context).languageCode; final String systemLang = Localizations.localeOf(context).languageCode;
final List<String> languagePriority = [systemLang, 'en', 'es']; final List<String> languagePriority = [systemLang, 'en', 'es'];
@ -65,16 +60,16 @@ class _PLanguageDropdownState extends State<PLanguageDropdown> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
DropdownButtonFormField2<LanguageModel>( DropdownButtonFormField<LanguageModel>(
decoration: InputDecoration(labelText: widget.decorationText), decoration: InputDecoration(labelText: decorationText),
isExpanded: true, isExpanded: true,
items: [ items: [
if (widget.showMultilingual) if (showMultilingual)
DropdownMenuItem( DropdownMenuItem(
value: LanguageModel.multiLingual(context), value: LanguageModel.multiLingual(context),
child: LanguageDropDownEntry( child: LanguageDropDownEntry(
languageModel: LanguageModel.multiLingual(context), languageModel: LanguageModel.multiLingual(context),
isL2List: widget.isL2List, isL2List: isL2List,
), ),
), ),
...sortedLanguages.map( ...sortedLanguages.map(
@ -82,17 +77,18 @@ class _PLanguageDropdownState extends State<PLanguageDropdown> {
value: languageModel, value: languageModel,
child: LanguageDropDownEntry( child: LanguageDropDownEntry(
languageModel: languageModel, languageModel: languageModel,
isL2List: widget.isL2List, isL2List: isL2List,
), ),
), ),
), ),
], ],
onChanged: (value) => widget.onChange(value!), onChanged: (value) => onChange(value!),
value: widget.initialLanguage, value: initialLanguage,
validator: (value) => validator?.call(value),
), ),
AnimatedSize( AnimatedSize(
duration: FluffyThemes.animationDuration, duration: FluffyThemes.animationDuration,
child: widget.error == null child: error == null
? const SizedBox.shrink() ? const SizedBox.shrink()
: Padding( : Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@ -100,7 +96,7 @@ class _PLanguageDropdownState extends State<PLanguageDropdown> {
vertical: 5, vertical: 5,
), ),
child: Text( child: Text(
widget.error!, error!,
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.error, color: Theme.of(context).colorScheme.error,
fontSize: 12, fontSize: 12,

Loading…
Cancel
Save