From 07cc5b9c329ec5686a27fba346ef2348824bcb12 Mon Sep 17 00:00:00 2001 From: William Jordan-Cooley Date: Mon, 14 Oct 2024 14:56:37 -0400 Subject: [PATCH 1/3] show beta and alpha tags on l2s --- assets/l10n/intl_en.arb | 6 +- lib/main.dart | 2 +- lib/pangea/enum/l2_support_enum.dart | 98 +++++++++++++++++++ lib/pangea/models/language_model.dart | 18 ++-- .../pages/find_partner/find_partner_view.dart | 1 + .../practice_activity_card.dart | 4 + .../user_settings/p_language_dialog.dart | 2 + .../user_settings/p_language_dropdown.dart | 10 ++ pubspec.yaml | 2 +- 9 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 lib/pangea/enum/l2_support_enum.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 437b6d075..282acab40 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4233,5 +4233,9 @@ "reportContentIssueTitle": "Report content issue", "feedback": "Optional feedback", "reportContentIssueDescription": "Uh oh! AI can faciliate personalized learning experiences but... also hallucinates. Please provide any feedback you have and we'll try again.", - "clickTheWordAgainToDeselect": "Click the selected word to deselect it." + "clickTheWordAgainToDeselect": "Click the selected word to deselect it.", + "l2SupportNa": "Not Available", + "l2SupportAlpha": "Alpha", + "l2SupportBeta": "Beta", + "l2SupportFull": "Full" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 6be6edc91..36add47dc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,7 +22,7 @@ void main() async { // #Pangea try { - await dotenv.load(fileName: ".env"); + await dotenv.load(fileName: ".env.local_choreo"); } catch (e) { Logs().e('Failed to load .env file', e); } diff --git a/lib/pangea/enum/l2_support_enum.dart b/lib/pangea/enum/l2_support_enum.dart new file mode 100644 index 000000000..c75534ea7 --- /dev/null +++ b/lib/pangea/enum/l2_support_enum.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +enum L2SupportEnum { + na, + alpha, + beta, + full, +} + +extension L2SupportEnumExtension on L2SupportEnum { + String get storageString { + switch (this) { + case L2SupportEnum.na: + return 'na'; + case L2SupportEnum.alpha: + return 'alpha'; + case L2SupportEnum.beta: + return 'beta'; + case L2SupportEnum.full: + return 'full'; + } + } + + L2SupportEnum fromStorageString(String storageString) { + switch (storageString) { + case 'na': + case 'L2SupportEnum.na': + return L2SupportEnum.na; + case 'alpha': + case 'L2SupportEnum.alpha': + return L2SupportEnum.alpha; + case 'beta': + case 'L2SupportEnum.beta': + return L2SupportEnum.beta; + case 'full': + case 'L2SupportEnum.full': + return L2SupportEnum.full; + default: + throw Exception('Unknown L2SupportEnum storage string: $storageString'); + } + } + + String toLocalizedString(BuildContext context) { + final l10n = L10n.of(context)!; + + switch (this) { + case L2SupportEnum.na: + return l10n.l2SupportNa; + case L2SupportEnum.alpha: + return l10n.l2SupportAlpha; + case L2SupportEnum.beta: + return l10n.l2SupportBeta; + case L2SupportEnum.full: + return l10n.l2SupportFull; + } + } + + Badge toBadge(BuildContext context) { + final theme = Theme.of(context); + Color color; + String label; + + switch (this) { + case L2SupportEnum.na: + color = theme.colorScheme.onSurface.withOpacity(0.4); // Muted grey + label = toLocalizedString(context); + break; + case L2SupportEnum.alpha: + color = theme.colorScheme.primary.withOpacity(0.4); // Subtle primary + label = toLocalizedString(context); + break; + case L2SupportEnum.beta: + color = + theme.colorScheme.secondary.withOpacity(0.4); // Subtle secondary + label = toLocalizedString(context); + break; + case L2SupportEnum.full: + color = theme.colorScheme.tertiary.withOpacity(0.4); // Subtle tertiary + label = toLocalizedString(context); + break; + } + + return Badge( + label: Text( + label, + style: theme.textTheme.bodySmall?.copyWith( + color: theme.colorScheme.onSurface.withOpacity(0.8), // Dimmed text + fontWeight: FontWeight.w500, + ), + ), + backgroundColor: color, + alignment: Alignment.center, + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + smallSize: 20, // A smaller badge for subtlety + ); + } +} diff --git a/lib/pangea/models/language_model.dart b/lib/pangea/models/language_model.dart index be3cc71ba..37c93f504 100644 --- a/lib/pangea/models/language_model.dart +++ b/lib/pangea/models/language_model.dart @@ -1,6 +1,7 @@ import 'dart:developer'; import 'package:fluffychat/pangea/constants/language_constants.dart'; +import 'package:fluffychat/pangea/enum/l2_support_enum.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -12,15 +13,15 @@ class LanguageModel { final String languageFlag; final String displayName; final String? languageEmoji; - final bool l2; final bool l1; + final L2SupportEnum l2Support; LanguageModel({ required this.langCode, required this.languageFlag, required this.displayName, - required this.l2, required this.l1, + this.l2Support = L2SupportEnum.na, this.languageEmoji, }); @@ -37,9 +38,11 @@ class LanguageModel { displayName: _LanguageLocal.getDisplayName( code != LanguageKeys.unknownLanguage ? code : json['language_name'], ), - l2: json["l2"] ?? code.contains("es") || code.contains("en"), l1: json["l1"] ?? !code.contains("es") && !code.contains("en"), languageEmoji: json['language_emoji'], + l2Support: json['l2_support'] != null + ? L2SupportEnum.na.fromStorageString(json['l2_support']) + : L2SupportEnum.na, ); } @@ -47,11 +50,13 @@ class LanguageModel { 'language_code': langCode, 'language_name': displayName, 'language_flag': languageFlag, - 'l2': l2, 'l1': l1, 'language_emoji': languageEmoji, + 'l2_support': l2Support.storageString, }; + bool get l2 => l2Support != L2SupportEnum.na; + // Discuss with Jordan - adding langCode field to language objects as separate from displayName static String codeFromNameOrCode(String codeOrName, [String? url]) { if (codeOrName.isEmpty) return LanguageKeys.unknownLanguage; @@ -73,7 +78,6 @@ class LanguageModel { langCode: LanguageKeys.unknownLanguage, languageFlag: "", displayName: "Unknown", - l2: false, l1: false, ); @@ -81,16 +85,12 @@ class LanguageModel { displayName: context != null ? L10n.of(context)!.multiLingualSpace : "Multilingual Space", - l2: false, l1: false, langCode: LanguageKeys.multiLanguage, languageFlag: 'assets/colors.png', languageEmoji: "🌎", ); - // Discuss with Jordan - bool get hasContextualDefinitionSupport => l2; - String? getDisplayName(BuildContext context) { switch (langCode) { case 'ab': diff --git a/lib/pangea/pages/find_partner/find_partner_view.dart b/lib/pangea/pages/find_partner/find_partner_view.dart index 032ed7daf..092c6eee1 100644 --- a/lib/pangea/pages/find_partner/find_partner_view.dart +++ b/lib/pangea/pages/find_partner/find_partner_view.dart @@ -234,6 +234,7 @@ class LanguageSelectionRow extends StatelessWidget { targetLanguage: isSource ? null : language, ); }, + isL2List: !isSource, initialLanguage: isSource ? controller.sourceLanguageSearch : controller.targetLanguageSearch, diff --git a/lib/pangea/widgets/practice_activity/practice_activity_card.dart b/lib/pangea/widgets/practice_activity/practice_activity_card.dart index 7e80e2aaa..442b1cf64 100644 --- a/lib/pangea/widgets/practice_activity/practice_activity_card.dart +++ b/lib/pangea/widgets/practice_activity/practice_activity_card.dart @@ -231,6 +231,10 @@ class MessagePracticeActivityCardState extends State { return; } + // clear the current activity and record + currentActivity = null; + currentCompletionRecord = null; + _fetchNewActivity( ActivityQualityFeedback( feedbackText: feedback, diff --git a/lib/pangea/widgets/user_settings/p_language_dialog.dart b/lib/pangea/widgets/user_settings/p_language_dialog.dart index b04b0e435..80dd7fa9d 100644 --- a/lib/pangea/widgets/user_settings/p_language_dialog.dart +++ b/lib/pangea/widgets/user_settings/p_language_dialog.dart @@ -63,6 +63,7 @@ Future pLanguageDialog( setState(() => selectedSourceLanguage = p0), initialLanguage: selectedSourceLanguage, languages: pangeaController.pLanguageStore.baseOptions, + isL2List: false, ), PQuestionContainer( title: L10n.of(parentContext)!.whatLanguageYouWantToLearn, @@ -72,6 +73,7 @@ Future pLanguageDialog( setState(() => selectedTargetLanguage = p0), initialLanguage: selectedTargetLanguage, languages: pangeaController.pLanguageStore.targetOptions, + isL2List: true, ), ], ), diff --git a/lib/pangea/widgets/user_settings/p_language_dropdown.dart b/lib/pangea/widgets/user_settings/p_language_dropdown.dart index 0793efdc2..19c2e71a5 100644 --- a/lib/pangea/widgets/user_settings/p_language_dropdown.dart +++ b/lib/pangea/widgets/user_settings/p_language_dropdown.dart @@ -1,5 +1,6 @@ // Flutter imports: +import 'package:fluffychat/pangea/enum/l2_support_enum.dart'; import 'package:fluffychat/pangea/models/language_model.dart'; import 'package:flutter/material.dart'; @@ -10,6 +11,7 @@ class PLanguageDropdown extends StatefulWidget { final LanguageModel initialLanguage; final Function(LanguageModel) onChange; final bool showMultilingual; + final bool isL2List; const PLanguageDropdown({ super.key, @@ -17,6 +19,7 @@ class PLanguageDropdown extends StatefulWidget { required this.onChange, required this.initialLanguage, this.showMultilingual = false, + required this.isL2List, }); @override @@ -98,6 +101,7 @@ class _PLanguageDropdownState extends State { value: LanguageModel.multiLingual(context), child: LanguageDropDownEntry( languageModel: LanguageModel.multiLingual(context), + isL2List: widget.isL2List, ), ), ...sortedLanguages.map( @@ -105,6 +109,7 @@ class _PLanguageDropdownState extends State { value: languageModel, child: LanguageDropDownEntry( languageModel: languageModel, + isL2List: widget.isL2List, ), ), ), @@ -118,9 +123,11 @@ class _PLanguageDropdownState extends State { class LanguageDropDownEntry extends StatelessWidget { final LanguageModel languageModel; + final bool isL2List; const LanguageDropDownEntry({ super.key, required this.languageModel, + required this.isL2List, }); @override @@ -144,6 +151,9 @@ class LanguageDropDownEntry extends StatelessWidget { overflow: TextOverflow.clip, textAlign: TextAlign.center, ), + const SizedBox(width: 10), + if (isL2List && languageModel.l2Support != L2SupportEnum.full) + languageModel.l2Support.toBadge(context), ], ), ); diff --git a/pubspec.yaml b/pubspec.yaml index d15833a5a..173fef435 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: 1.21.4+3539 +version: 1.21.4+3540 environment: sdk: ">=3.0.0 <4.0.0" From 5f0439d0d42e02070aacd19a14924b191dde81f4 Mon Sep 17 00:00:00 2001 From: wcjord <32568597+wcjord@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:59:15 -0400 Subject: [PATCH 2/3] Update main.dart Remove change to env path... --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 36add47dc..6be6edc91 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,7 +22,7 @@ void main() async { // #Pangea try { - await dotenv.load(fileName: ".env.local_choreo"); + await dotenv.load(fileName: ".env"); } catch (e) { Logs().e('Failed to load .env file', e); } From b463558b1a35f7bdaff7e44e27ea0c29cbda7062 Mon Sep 17 00:00:00 2001 From: William Jordan-Cooley Date: Mon, 14 Oct 2024 17:00:15 -0400 Subject: [PATCH 3/3] fixing edge case of no l2s --- lib/pangea/controllers/language_list_controller.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pangea/controllers/language_list_controller.dart b/lib/pangea/controllers/language_list_controller.dart index 77f4ae9e2..7380f3e3f 100644 --- a/lib/pangea/controllers/language_list_controller.dart +++ b/lib/pangea/controllers/language_list_controller.dart @@ -27,7 +27,9 @@ class PangeaLanguage { static Future initialize() async { try { _langList = await _getCachedFlags(); - if (await _shouldFetch || _langList.isEmpty) { + if (await _shouldFetch || + _langList.isEmpty || + _langList.every((lang) => !lang.l2)) { _langList = await LanguageRepo.fetchLanguages(); await _saveFlags(_langList);