feat: add submit button to learning settings popup (#1717)

pull/1593/head
ggurdin 9 months ago committed by GitHub
parent 18cbb45fe1
commit 5347b4764f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -352,9 +352,12 @@ class ChatController extends State<ChatPageWithRoom>
_levelSubscription = pangeaController.getAnalytics.analyticsStream.stream
.where((update) => update.levelUp)
.listen(
(update) => LevelUpUtil.showLevelUpDialog(
pangeaController.getAnalytics.constructListModel.level,
context,
(update) => Future.delayed(
const Duration(milliseconds: 500),
() => LevelUpUtil.showLevelUpDialog(
pangeaController.getAnalytics.constructListModel.level,
context,
),
),
);
// Pangea#

@ -50,4 +50,8 @@ class InstructionSettings {
void setStatus(InstructionsEnum instruction, bool status) {
_instructions[instruction.toString()] = status;
}
InstructionSettings copy() {
return InstructionSettings(Map<String, bool>.from(_instructions));
}
}

@ -7,7 +7,6 @@ import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_en
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';
@ -23,27 +22,15 @@ class SettingsLearning extends StatefulWidget {
class SettingsLearningController extends State<SettingsLearning> {
PangeaController pangeaController = MatrixState.pangeaController;
late Profile _profile;
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();
_profile = pangeaController.userController.profile.copy();
tts.setupTTS().then((_) => setState(() {}));
}
@ -53,87 +40,73 @@ class SettingsLearningController extends State<SettingsLearning> {
super.dispose();
}
Future<void> submit() async {
if (formKey.currentState!.validate()) {
await showFutureLoadingDialog(
context: context,
future: () async => pangeaController.userController.updateProfile(
(_) => _profile,
),
);
Navigator.of(context).pop();
}
}
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 (sourceLanguage != null) {
_profile.userSettings.sourceLanguage = sourceLanguage.langCode;
}
if (targetLanguage != null) {
_profile.userSettings.targetLanguage = targetLanguage.langCode;
}
if (mounted) setState(() {});
}
void setPublicProfile(bool isPublic) {
pangeaController.userController.updateProfile(
(profile) {
// set user DOB to younger that 18 if private and older than 18 if public
profile.userSettings.publicProfile = isPublic;
return profile;
},
);
setState(() {});
_profile.userSettings.publicProfile = isPublic;
if (mounted) setState(() {});
}
void setCefrLevel(LanguageLevelTypeEnum? cefrLevel) {
pangeaController.userController.updateProfile(
(profile) {
profile.userSettings.cefrLevel = cefrLevel ?? LanguageLevelTypeEnum.a1;
return profile;
},
);
setState(() {});
}
void changeLanguage() {
pLanguageDialog(context, () {}).then((_) => setState(() {}));
_profile.userSettings.cefrLevel = cefrLevel ?? LanguageLevelTypeEnum.a1;
if (mounted) setState(() {});
}
void changeCountry(Country country) {
pangeaController.userController.updateProfile((Profile profile) {
profile.userSettings.country = country.displayNameNoCountryCode;
return profile;
});
setState(() {});
_profile.userSettings.country = country.displayNameNoCountryCode;
if (mounted) setState(() {});
}
void updateToolSetting(ToolSetting toolSetting, bool value) {
pangeaController.userController.updateProfile((Profile profile) {
switch (toolSetting) {
case ToolSetting.interactiveTranslator:
return profile..toolSettings.interactiveTranslator = value;
case ToolSetting.interactiveGrammar:
return profile..toolSettings.interactiveGrammar = value;
case ToolSetting.immersionMode:
return profile..toolSettings.immersionMode = value;
case ToolSetting.definitions:
return profile..toolSettings.definitions = value;
case ToolSetting.autoIGC:
return profile..toolSettings.autoIGC = value;
case ToolSetting.enableTTS:
return profile..toolSettings.enableTTS = value;
}
});
switch (toolSetting) {
case ToolSetting.interactiveTranslator:
_profile.toolSettings.interactiveTranslator = value;
break;
case ToolSetting.interactiveGrammar:
_profile.toolSettings.interactiveGrammar = value;
break;
case ToolSetting.immersionMode:
_profile.toolSettings.immersionMode = value;
break;
case ToolSetting.definitions:
_profile.toolSettings.definitions = value;
break;
case ToolSetting.autoIGC:
_profile.toolSettings.autoIGC = value;
break;
case ToolSetting.enableTTS:
_profile.toolSettings.enableTTS = value;
break;
}
if (mounted) setState(() {});
}
bool getToolSetting(ToolSetting toolSetting) {
final toolSettings = pangeaController.userController.profile.toolSettings;
final toolSettings = _profile.toolSettings;
switch (toolSetting) {
case ToolSetting.interactiveTranslator:
return toolSettings.interactiveTranslator;
@ -150,11 +123,29 @@ class SettingsLearningController extends State<SettingsLearning> {
}
}
bool get publicProfile =>
pangeaController.userController.profile.userSettings.publicProfile;
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 => _profile.userSettings.sourceLanguage != null
? PangeaLanguage.byLangCode(_profile.userSettings.sourceLanguage!)
: null;
LanguageModel? get userL2 => _profile.userSettings.targetLanguage != null
? PangeaLanguage.byLangCode(_profile.userSettings.targetLanguage!)
: null;
bool get publicProfile => _profile.userSettings.publicProfile;
LanguageLevelTypeEnum get cefrLevel => _profile.userSettings.cefrLevel;
LanguageLevelTypeEnum get cefrLevel =>
pangeaController.userController.profile.userSettings.cefrLevel;
String? get country => _profile.userSettings.country;
@override
Widget build(BuildContext context) {

@ -15,7 +15,6 @@ import 'package:fluffychat/pangea/learning_settings/widgets/p_language_dropdown.
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';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:fluffychat/widgets/matrix.dart';
class SettingsLearningView extends StatelessWidget {
@ -45,125 +44,178 @@ class SettingsLearningView extends StatelessWidget {
),
body: ListTileTheme(
iconColor: Theme.of(context).textTheme.bodyLarge!.color,
child: MaxWidthBody(
withScrolling: true,
child: Form(
key: controller.formKey,
child: Form(
key: controller.formKey,
child: Padding(
padding: const EdgeInsets.all(16.0),
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 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,
),
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),
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
spacing: 16.0,
children: [
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;
},
),
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,
);
},
),
],
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;
},
),
CountryPickerTile(controller),
LanguageLevelDropdown(
initialLevel: controller.cefrLevel,
onChanged: controller.setCefrLevel,
),
const Divider(height: 1),
Column(
children: [
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),
),
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,
);
},
),
],
),
),
),
],
),
SwitchListTile.adaptive(
value: controller.publicProfile,
onChanged: controller.setPublicProfile,
title: Text(
L10n.of(context).publicProfileTitle,
),
subtitle: Text(
L10n.of(context).publicProfileDesc,
),
activeColor: AppConfig.activeToggleColor,
),
],
),
),
],
],
),
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: controller.submit,
child: Text(L10n.of(context).submit),
),
),
SwitchListTile.adaptive(
value: controller.publicProfile,
onChanged: controller.setPublicProfile,
title: Text(L10n.of(context).publicProfileTitle),
subtitle: Text(L10n.of(context).publicProfileDesc),
activeColor: AppConfig.activeToggleColor,
),
],
),
@ -175,7 +227,7 @@ class SettingsLearningView extends StatelessWidget {
return FullWidthDialog(
dialogContent: dialogContent,
maxWidth: 600,
maxHeight: 600,
maxHeight: 800,
);
},
);

@ -7,7 +7,6 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/learning_settings/pages/settings_learning.dart';
import 'package:fluffychat/pangea/learning_settings/utils/country_display.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../user/models/user_model.dart';
class CountryPickerTile extends StatelessWidget {
final SettingsLearningController learningController;
@ -17,16 +16,14 @@ class CountryPickerTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
final Profile profile = pangeaController.userController.profile;
final String displayName = CountryDisplayUtil.countryDisplayName(
profile.userSettings.country,
learningController.country,
context,
) ??
'';
final String flag = CountryDisplayUtil.flagEmoji(
profile.userSettings.country,
learningController.country,
);
return ListTile(

@ -1,90 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'package:fluffychat/pangea/learning_settings/pages/settings_learning.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'flag.dart';
//PTODO - move this to settings_learning_view.dart and make callback a setState
class LanguageTile extends StatelessWidget {
final SettingsLearningController learningController;
final PangeaController pangeaController = MatrixState.pangeaController;
LanguageTile(this.learningController, {super.key});
@override
Widget build(BuildContext context) {
final LanguageModel? sourceLanguage =
pangeaController.languageController.userL1;
final LanguageModel? targetLanguage =
pangeaController.languageController.userL2;
//PTODO - placeholder saying 'select your languages'
// if (targetLanguage == null || sourceLanguage == null) {
// debugger(when: kDebugMode);
// return const SizedBox();
// }
return ListTile(
// title: Row(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.start,
// children: const [
// Text("Source Language"),
// SizedBox(
// width: 10,
// ),
// Icon(Icons.arrow_right_alt_outlined, size: 20),
// SizedBox(
// width: 10,
// ),
// Text("Target Language"),
// ]),
title: Text(L10n.of(context).myLanguages),
subtitle: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
LanguageFlag(
language: sourceLanguage,
),
const SizedBox(
width: 10,
),
Text(
sourceLanguage?.getDisplayName(context) ??
L10n.of(context).sourceLanguage,
),
const SizedBox(
width: 10,
),
const Icon(Icons.arrow_right_alt_outlined, size: 20),
const SizedBox(
width: 10,
),
LanguageFlag(
language: targetLanguage,
),
const SizedBox(
width: 10,
),
Text(
targetLanguage?.getDisplayName(context) ??
L10n.of(context).targetLanguage,
),
],
),
trailing: const Icon(Icons.edit_outlined),
onTap: () async {
learningController.changeLanguage();
},
);
}
}

@ -128,6 +128,21 @@ class UserSettings {
as String?,
);
}
UserSettings copy() {
return UserSettings(
dateOfBirth: dateOfBirth,
createdAt: createdAt,
autoPlayMessages: autoPlayMessages,
activatedFreeTrial: activatedFreeTrial,
publicProfile: publicProfile,
targetLanguage: targetLanguage,
sourceLanguage: sourceLanguage,
country: country,
hasJoinedHelpSpace: hasJoinedHelpSpace,
cefrLevel: cefrLevel,
);
}
}
/// The user's language tool settings.
@ -194,6 +209,17 @@ class UserToolSettings {
true,
);
}
UserToolSettings copy() {
return UserToolSettings(
interactiveTranslator: interactiveTranslator,
interactiveGrammar: interactiveGrammar,
immersionMode: immersionMode,
definitions: definitions,
autoIGC: autoIGC,
enableTTS: enableTTS,
);
}
}
/// A wrapper around the matrix account data for the user profile.
@ -305,6 +331,14 @@ class Profile {
instructionSettings: InstructionSettings(),
);
}
Profile copy() {
return Profile(
userSettings: userSettings.copy(),
toolSettings: toolSettings.copy(),
instructionSettings: instructionSettings.copy(),
);
}
}
/// Model of data from pangea chat server. Not used anymore, in favor of matrix account data.

Loading…
Cancel
Save