Skip to content

Commit

Permalink
feat: move language dropdowns into learning settings dialog (#1695)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggurdin authored Feb 4, 2025
1 parent 75a0d1e commit 1e40e1d
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 95 deletions.
46 changes: 46 additions & 0 deletions lib/pangea/learning_settings/pages/settings_learning.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import 'package:country_picker/country_picker.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/models/language_model.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/spaces/models/space_model.dart';
import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart';
import 'package:fluffychat/pangea/user/models/user_model.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';

class SettingsLearning extends StatefulWidget {
Expand All @@ -22,6 +25,22 @@ class SettingsLearningController extends State<SettingsLearning> {
PangeaController pangeaController = MatrixState.pangeaController;
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
void initState() {
super.initState();
Expand All @@ -34,6 +53,33 @@ class SettingsLearningController extends State<SettingsLearning> {
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) {
pangeaController.userController.updateProfile(
(profile) {
Expand Down
193 changes: 116 additions & 77 deletions lib/pangea/learning_settings/pages/settings_learning_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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/common/constants/model_keys.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/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/spaces/models/space_model.dart';
import 'package:fluffychat/utils/platform_infos.dart';
Expand Down Expand Up @@ -46,88 +47,126 @@ class SettingsLearningView extends StatelessWidget {
iconColor: Theme.of(context).textTheme.bodyLarge!.color,
child: MaxWidthBody(
withScrolling: true,
child: Column(
children: [
LanguageTile(controller),
CountryPickerTile(controller),
Padding(
padding: const EdgeInsets.only(top: 16.0, bottom: 24.0),
child: LanguageLevelDropdown(
initialLevel: controller.cefrLevel,
onChanged: controller.setCefrLevel,
child: Form(
key: controller.formKey,
child: Column(
children: [
const SizedBox(height: 8.0),
PLanguageDropdown(
onChange: (lang) =>
controller.setSelectedLanguage(sourceLanguage: lang),
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 Divider(height: 1),
ListTile(
title: Text(L10n.of(context).toggleToolSettingsDescription),
),
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,
),
enabled: toolSetting == ToolSetting.enableTTS
? controller.tts.isLanguageFullySupported
: true,
),
if (toolSetting == ToolSetting.enableTTS &&
!controller.tts.isLanguageFullySupported)
ListTile(
trailing: const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Icon(Icons.info_outlined),
const SizedBox(height: 24.0),
PLanguageDropdown(
onChange: (lang) =>
controller.setSelectedLanguage(targetLanguage: lang),
initialLanguage: controller.selectedTargetLanguage,
languages: MatrixState
.pangeaController.pLanguageStore.targetOptions,
isL2List: true,
decorationText: L10n.of(context).iWantToLearn,
validator: (lang) {
if (lang == controller.selectedSourceLanguage) {
return L10n.of(context).noIdenticalLanguages;
}
return null;
},
),
const SizedBox(height: 16.0),
CountryPickerTile(controller),
Padding(
padding: const EdgeInsets.only(top: 16.0, bottom: 24.0),
child: LanguageLevelDropdown(
initialLevel: controller.cefrLevel,
onChanged: controller.setCefrLevel,
),
),
const Divider(height: 1),
ListTile(
title:
Text(L10n.of(context).toggleToolSettingsDescription),
),
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(
text: TextSpan(
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,
enabled: toolSetting == ToolSetting.enableTTS
? controller.tts.isLanguageFullySupported
: true,
),
if (toolSetting == ToolSetting.enableTTS &&
!controller.tts.isLanguageFullySupported)
ListTile(
trailing: const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Icon(Icons.info_outlined),
),
subtitle: RichText(
text: TextSpan(
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,
),
],
],
),
),
),
),
Expand Down
32 changes: 14 additions & 18 deletions lib/pangea/learning_settings/widgets/p_language_dropdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@

import 'package:flutter/material.dart';

import 'package:dropdown_button2/dropdown_button2.dart';

import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pangea/learning_settings/enums/l2_support_enum.dart';
import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'flag.dart';

class PLanguageDropdown extends StatefulWidget {
class PLanguageDropdown extends StatelessWidget {
final List<LanguageModel> languages;
final LanguageModel? initialLanguage;
final Function(LanguageModel) onChange;
final bool showMultilingual;
final bool isL2List;
final String decorationText;
final String? error;
final String? Function(LanguageModel?)? validator;

const PLanguageDropdown({
super.key,
Expand All @@ -27,16 +26,12 @@ class PLanguageDropdown extends StatefulWidget {
required this.decorationText,
this.isL2List = false,
this.error,
this.validator,
});

@override
State<PLanguageDropdown> createState() => _PLanguageDropdownState();
}

class _PLanguageDropdownState extends State<PLanguageDropdown> {
@override
Widget build(BuildContext context) {
final List<LanguageModel> sortedLanguages = widget.languages;
final List<LanguageModel> sortedLanguages = languages;
final String systemLang = Localizations.localeOf(context).languageCode;
final List<String> languagePriority = [systemLang, 'en', 'es'];

Expand Down Expand Up @@ -65,42 +60,43 @@ class _PLanguageDropdownState extends State<PLanguageDropdown> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
DropdownButtonFormField2<LanguageModel>(
decoration: InputDecoration(labelText: widget.decorationText),
DropdownButtonFormField<LanguageModel>(
decoration: InputDecoration(labelText: decorationText),
isExpanded: true,
items: [
if (widget.showMultilingual)
if (showMultilingual)
DropdownMenuItem(
value: LanguageModel.multiLingual(context),
child: LanguageDropDownEntry(
languageModel: LanguageModel.multiLingual(context),
isL2List: widget.isL2List,
isL2List: isL2List,
),
),
...sortedLanguages.map(
(languageModel) => DropdownMenuItem(
value: languageModel,
child: LanguageDropDownEntry(
languageModel: languageModel,
isL2List: widget.isL2List,
isL2List: isL2List,
),
),
),
],
onChanged: (value) => widget.onChange(value!),
value: widget.initialLanguage,
onChanged: (value) => onChange(value!),
value: initialLanguage,
validator: (value) => validator?.call(value),
),
AnimatedSize(
duration: FluffyThemes.animationDuration,
child: widget.error == null
child: error == null
? const SizedBox.shrink()
: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30,
vertical: 5,
),
child: Text(
widget.error!,
error!,
style: TextStyle(
color: Theme.of(context).colorScheme.error,
fontSize: 12,
Expand Down

0 comments on commit 1e40e1d

Please sign in to comment.