diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 2ceb36709..a87697a15 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4115,14 +4115,14 @@ "placeholders": {} }, "addChatToSpaceDesc": "Adding a chat to a space will make the chat appear within the space for students and give them access.", - "addSpaceToSpaceDesc": "Adding a sub space to space will make the sub space appear in the main space's chat list.", + "addSpaceToSpaceDesc": "Adding a sub space to space will make the sub space appear in the main space''s chat list.", "spaceAnalytics": "Space Analytics", "changeAnalyticsLanguage": "Change Analytics Language", "suggestToSpace": "Suggest this space", - "suggestToSpaceDesc": "Suggested sub spaces will appear in their main space's chat list", + "suggestToSpaceDesc": "Suggested sub spaces will appear in their main space''s chat list", "practice": "Practice", "noLanguagesSet": "No languages set", - "noActivitiesFound": "That's enough on this for now! Come back later for more.", + "noActivitiesFound": "That''s enough on this for now! Come back later for more.", "hintTitle": "Hint:", "speechToTextBody": "See how well you did by looking at your Accuracy and Words Per Minute scores", "previous": "Previous", @@ -4226,17 +4226,135 @@ "discoverHomeservers": "Discover homeservers", "whatIsAHomeserver": "What is a homeserver?", "homeserverDescription": "All your data is stored on the homeserver, just like an email provider. You can choose which homeserver you want to use, while you can still communicate with everyone. Learn more at at https://matrix.org.", - "doesNotSeemToBeAValidHomeserver": "Doesn't seem to be a compatible homeserver. Wrong URL?", + "doesNotSeemToBeAValidHomeserver": "Doesn''t seem to be a compatible homeserver. Wrong URL?", "grammar": "Grammar", "contactHasBeenInvitedToTheChat": "Contact has been invited to the chat", "inviteChat": "📨 Invite chat", "chatName": "Chat name", "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.", + "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.", "l2SupportNa": "Not Available", "l2SupportAlpha": "Alpha", "l2SupportBeta": "Beta", - "l2SupportFull": "Full" + "l2SupportFull": "Full", + "grammarCopySCONJ": "Subordinating Conjunction", + "grammarCopyNUM": "Number", + "grammarCopyVERB": "Verb", + "grammarCopyAFFIX": "Affix", + "grammarCopyPARTpos": "Particle", + "grammarCopyADJ": "Adjective", + "grammarCopyCCONJ": "Coordinating Conjunction", + "grammarCopyPUNCT": "Punctuation", + "grammarCopyADV": "Adverb", + "grammarCopyAUX": "Auxiliary", + "grammarCopySPACE": "Space", + "grammarCopySYM": "Symbol", + "grammarCopyDET": "Determiner", + "grammarCopyPRON": "Pronoun", + "grammarCopyADP": "Adposition", + "grammarCopyPROPN": "Proper Noun", + "grammarCopyNOUN": "Noun", + "grammarCopyINTJ": "Interjection", + "grammarCopyX": "Other", + "grammarCopyFem": "Feminine", + "grammarCopy2": "Second Person", + "grammarCopyImp": "Imperative", + "grammarCopyQest": "Question", + "grammarCopyPerf": "Perfect", + "grammarCopyAccNom": "Accusative, Nominative", + "grammarCopyObl": "Oblique Case", + "grammarCopyAct": "Active", + "grammarCopyBrck": "Bracket", + "grammarCopyArt": "Article", + "grammarCopySing": "Singular", + "grammarCopyMasc": "Masculine", + "grammarCopyMod": "Modal", + "grammarCopyAdverbial": "Adverbial", + "grammarCopyPeri": "Periphrastic", + "grammarCopyDigit": "Digit", + "grammarCopyNot_proper": "Not Proper", + "grammarCopyCard": "Cardinal", + "grammarCopyProp": "Proper", + "grammarCopyDash": "Dash", + "grammarCopyYes": "Yes", + "grammarCopySemi": "Semicolon", + "grammarCopyComm": "Comma", + "grammarCopyCnd": "Conditional", + "grammarCopyIntRel": "Interrogative, Relative", + "grammarCopyAcc": "Accusative", + "grammarCopyPartTag": "Partitive", + "grammarCopyInt": "Interrogative", + "grammarCopyPast": "Past", + "grammarCopySup": "Superlative", + "grammarCopyColo": "Colon", + "grammarCopy3": "Third Person", + "grammarCopyPlur": "Plural", + "grammarCopyNpr": "Proper Noun", + "grammarCopyInterrogative": "Interrogative", + "grammarCopyInfm": "Informal", + "grammarCopyTim": "Time", + "grammarCopyNeg": "Negative", + "grammarCopyTot": "Total", + "grammarCopyAdnomial": "Adnominal", + "grammarCopyProg": "Progressive", + "grammarCopySub": "Subjunctive", + "grammarCopyComplementive": "Complementive", + "grammarCopyNom": "Nominative", + "grammarCopyFut": "Future", + "grammarCopyDat": "Dative", + "grammarCopyPres": "Present", + "grammarCopyNeut": "Neuter", + "grammarCopyRel": "Relative", + "grammarCopyFinal_ending": "Final Ending", + "grammarCopyDem": "Demonstrative", + "grammarCopyPre": "Preposition", + "grammarCopyFin": "Finite", + "grammarCopyPos": "Positive", + "grammarCopyQuot": "Quotation", + "grammarCopyGer": "Gerund", + "grammarCopyPass": "Passive", + "grammarCopyGen": "Genitive", + "grammarCopyPrs": "Present", + "grammarCopyDef": "Definite", + "grammarCopyOrd": "Ordinal", + "grammarCopyIns": "Instrumental", + "grammarCopyAccDat": "Accusative, Dative", + "grammarCopyInf": "Infinitive", + "grammarCopyLong": "Long", + "grammarCopyInd": "Indicative", + "grammarCopyCmp": "Comparative", + "grammarCopyRelative_case": "Relative Case", + "grammarCopyExcl": "Exclamative", + "grammarCopy1": "First Person", + "grammarCopyIni": "Initial", + "grammarCopyPerson": "Person", + "grammarCopyForeign": "Foreign", + "grammarCopyVoice": "Voice", + "grammarCopyVerbType": "Verb Type", + "grammarCopyPoss": "Possessive", + "grammarCopyPrepCase": "Prepositional Case", + "grammarCopyNumType": "Numeral Type", + "grammarCopyNounType": "Noun Type", + "grammarCopyReflex": "Reflexive", + "grammarCopyPronType": "Pronoun Type", + "grammarCopyPunctSide": "Punctuation Side", + "grammarCopyVerbForm": "Verb Form", + "grammarCopyGender": "Gender", + "grammarCopyMood": "Mood", + "grammarCopyAspect": "Aspect", + "grammarCopyPunctType": "Punctuation Type", + "grammarCopyTense": "Tense", + "grammarCopyDegree": "Degree", + "grammarCopyPolite": "Politeness", + "grammarCopyAdvType": "Adverb Type", + "grammarCopyNumber": "Number", + "grammarCopyConjType": "Conjunction Type", + "grammarCopyPolarity": "Polarity", + "grammarCopyNumberPsor": "Possessor''s Number", + "grammarCopyCase": "Case", + "grammarCopyDefinite": "Definiteness", + "grammarCopyNumForm": "Numeral Form", + "grammarCopyUnknown": "Unknown" } \ No newline at end of file diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 5c5d1b840..edf277e86 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -402,64 +402,6 @@ class ChatDetailsView extends StatelessWidget { startOpen: false, ), const Divider(height: 1), - if (!room.isDirectChat) - if (room.isRoomAdmin) - ListTile( - title: Text( - room.isSpace - ? L10n.of(context)!.archiveSpace - : L10n.of(context)!.archive, - style: TextStyle( - color: - Theme.of(context).colorScheme.secondary, - fontWeight: FontWeight.bold, - ), - ), - leading: CircleAvatar( - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: const Icon( - Icons.archive_outlined, - ), - ), - onTap: () async { - var confirmed = OkCancelResult.ok; - var shouldGo = false; - // archiveSpace has its own popup; only show if not space - if (!room.isSpace) { - confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.ok, - cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)! - .archiveRoomDescription, - ); - } - if (confirmed == OkCancelResult.ok) { - if (room.isSpace) { - shouldGo = await room.archiveSpace( - context, - Matrix.of(context).client, - ); - } else { - final success = - await showFutureLoadingDialog( - context: context, - future: () async { - await room.archive(); - }, - ); - shouldGo = (success.error == null); - } - if (shouldGo) { - context.go('/rooms'); - } - } - }, - ), ListTile( title: Text( L10n.of(context)!.leave, diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart index 286b5d8e9..d63776272 100644 --- a/lib/pages/settings/settings_view.dart +++ b/lib/pages/settings/settings_view.dart @@ -4,6 +4,7 @@ import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:go_router/go_router.dart'; @@ -18,14 +19,6 @@ class SettingsView extends StatelessWidget { const SettingsView(this.controller, {super.key}); - // #Pangea - Future getAppVersion(BuildContext context) async { - final packageInfo = await PackageInfo.fromPlatform(); - return L10n.of(context)! - .versionText(packageInfo.version, packageInfo.buildNumber); - } - // Pangea# - @override Widget build(BuildContext context) { final theme = Theme.of(context); @@ -218,14 +211,34 @@ class SettingsView extends StatelessWidget { onTap: () => launchUrlString(AppConfig.termsOfServiceUrl), trailing: const Icon(Icons.open_in_new_outlined), ), - FutureBuilder( - future: getAppVersion(context), + FutureBuilder( + future: PackageInfo.fromPlatform(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return ListTile( leading: const Icon(Icons.info_outline), + trailing: const Icon(Icons.copy_outlined), + onTap: () async { + if (snapshot.data == null) return; + await Clipboard.setData( + ClipboardData( + text: + "${snapshot.data!.version}+${snapshot.data!.buildNumber}", + ), + ); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.copiedToClipboard), + ), + ); + }, title: Text( - snapshot.data ?? L10n.of(context)!.versionNotFound, + snapshot.data != null + ? L10n.of(context)!.versionText( + snapshot.data!.version, + snapshot.data!.buildNumber, + ) + : L10n.of(context)!.versionNotFound, ), ); } else if (snapshot.hasError) { diff --git a/lib/pangea/constants/bot_mode.dart b/lib/pangea/constants/bot_mode.dart index fbdd24b6f..ae96ec36d 100644 --- a/lib/pangea/constants/bot_mode.dart +++ b/lib/pangea/constants/bot_mode.dart @@ -1,5 +1,5 @@ class BotMode { - static const direct = "direct"; + static const directChat = "direct_chat"; static const discussion = "discussion"; static const custom = "custom"; static const storyGame = "story_game"; diff --git a/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart b/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart index a88551336..69494ac4f 100644 --- a/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart @@ -56,7 +56,7 @@ extension RoomInformationRoomExtension on Room { ); } - Future get _isBotDM async => botOptions?.mode == BotMode.direct; + Future get _isBotDM async => botOptions?.mode == BotMode.directChat; bool get _isLocked { if (isDirectChat) return false; diff --git a/lib/pangea/models/space_model.dart b/lib/pangea/models/space_model.dart index 232899bb8..402ba0a14 100644 --- a/lib/pangea/models/space_model.dart +++ b/lib/pangea/models/space_model.dart @@ -269,4 +269,16 @@ extension SettingCopy on ToolSetting { return L10n.of(context)!.autoIGCToolDescription; } } + + bool get isAvailableSetting { + switch (this) { + case ToolSetting.interactiveTranslator: + case ToolSetting.interactiveGrammar: + case ToolSetting.definitions: + return false; + case ToolSetting.immersionMode: + case ToolSetting.autoIGC: + return true; + } + } } diff --git a/lib/pangea/pages/settings_learning/settings_learning.dart b/lib/pangea/pages/settings_learning/settings_learning.dart index 3e0a11e4c..368d0a7c3 100644 --- a/lib/pangea/pages/settings_learning/settings_learning.dart +++ b/lib/pangea/pages/settings_learning/settings_learning.dart @@ -8,7 +8,11 @@ import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; class SettingsLearning extends StatefulWidget { - const SettingsLearning({super.key}); + final bool isPopup; + const SettingsLearning({ + this.isPopup = false, + super.key, + }); @override SettingsLearningController createState() => SettingsLearningController(); diff --git a/lib/pangea/pages/settings_learning/settings_learning_view.dart b/lib/pangea/pages/settings_learning/settings_learning_view.dart index 1a6576770..835dbb774 100644 --- a/lib/pangea/pages/settings_learning/settings_learning_view.dart +++ b/lib/pangea/pages/settings_learning/settings_learning_view.dart @@ -19,6 +19,12 @@ class SettingsLearningView extends StatelessWidget { title: Text( L10n.of(context)!.learningSettings, ), + leading: controller.widget.isPopup + ? IconButton( + icon: const Icon(Icons.close), + onPressed: Navigator.of(context).pop, + ) + : null, ), body: ListTileTheme( iconColor: Theme.of(context).textTheme.bodyLarge!.color, @@ -28,22 +34,12 @@ class SettingsLearningView extends StatelessWidget { children: [ LanguageTile(controller), CountryPickerTile(controller), - const SizedBox(height: 8), const Divider(height: 1), - const SizedBox(height: 8), - // if (controller.pangeaController.permissionsController.isUser18()) - // SwitchListTile.adaptive( - // activeColor: AppConfig.activeToggleColor, - // title: Text(L10n.of(context)!.publicProfileTitle), - // subtitle: Text(L10n.of(context)!.publicProfileDesc), - // value: controller.pangeaController.userController.isPublic, - // onChanged: (bool isPublicProfile) => - // controller.setPublicProfile(isPublicProfile), - // ), ListTile( - subtitle: Text(L10n.of(context)!.toggleToolSettingsDescription), + title: Text(L10n.of(context)!.toggleToolSettingsDescription), ), - for (final toolSetting in ToolSetting.values) + for (final toolSetting in ToolSetting.values + .where((tool) => tool.isAvailableSetting)) ProfileSettingsSwitchListTile.adaptive( defaultValue: controller.getToolSetting(toolSetting), title: toolSetting.toolName(context), @@ -66,18 +62,18 @@ class SettingsLearningView extends StatelessWidget { return profile; }), ), - ProfileSettingsSwitchListTile.adaptive( - defaultValue: controller.pangeaController.userController.profile - .userSettings.autoPlayMessages, - title: L10n.of(context)!.autoPlayTitle, - subtitle: L10n.of(context)!.autoPlayDesc, - onChange: (bool value) => controller - .pangeaController.userController - .updateProfile((profile) { - profile.userSettings.autoPlayMessages = value; - return profile; - }), - ), + // ProfileSettingsSwitchListTile.adaptive( + // defaultValue: controller.pangeaController.userController.profile + // .userSettings.autoPlayMessages, + // title: L10n.of(context)!.autoPlayTitle, + // subtitle: L10n.of(context)!.autoPlayDesc, + // onChange: (bool value) => controller + // .pangeaController.userController + // .updateProfile((profile) { + // profile.userSettings.autoPlayMessages = value; + // return profile; + // }), + // ), ], ), ), diff --git a/lib/pangea/utils/get_grammar_copy.dart b/lib/pangea/utils/get_grammar_copy.dart new file mode 100644 index 000000000..31a907c36 --- /dev/null +++ b/lib/pangea/utils/get_grammar_copy.dart @@ -0,0 +1,267 @@ +import 'dart:developer'; + +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +String getGrammarCopy(String tag, BuildContext context) { + switch (tag) { + case 'SCONJ': + return L10n.of(context)!.grammarCopySCONJ; + case 'NUM': + return L10n.of(context)!.grammarCopyNUM; + case 'VERB': + return L10n.of(context)!.grammarCopyVERB; + case 'AFFIX': + return L10n.of(context)!.grammarCopyAFFIX; + case 'PART': + return L10n.of(context)!.grammarCopyPARTpos; + case 'ADJ': + return L10n.of(context)!.grammarCopyADJ; + case 'CCONJ': + return L10n.of(context)!.grammarCopyCCONJ; + case 'PUNCT': + return L10n.of(context)!.grammarCopyPUNCT; + case 'ADV': + return L10n.of(context)!.grammarCopyADV; + case 'AUX': + return L10n.of(context)!.grammarCopyAUX; + case 'SPACE': + return L10n.of(context)!.grammarCopySPACE; + case 'SYM': + return L10n.of(context)!.grammarCopySYM; + case 'DET': + return L10n.of(context)!.grammarCopyDET; + case 'PRON': + return L10n.of(context)!.grammarCopyPRON; + case 'ADP': + return L10n.of(context)!.grammarCopyADP; + case 'PROPN': + return L10n.of(context)!.grammarCopyPROPN; + case 'NOUN': + return L10n.of(context)!.grammarCopyNOUN; + case 'INTJ': + return L10n.of(context)!.grammarCopyINTJ; + case 'X': + return L10n.of(context)!.grammarCopyX; + case 'Fem': + return L10n.of(context)!.grammarCopyFem; + case '2': + return L10n.of(context)!.grammarCopy2; + case 'Imp': + return L10n.of(context)!.grammarCopyImp; + case 'Qest': + return L10n.of(context)!.grammarCopyQest; + case 'Perf': + return L10n.of(context)!.grammarCopyPerf; + case 'Acc,Nom': + return L10n.of(context)!.grammarCopyAccNom; + case 'Obl': + return L10n.of(context)!.grammarCopyObl; + case 'Act': + return L10n.of(context)!.grammarCopyAct; + case 'Brck': + return L10n.of(context)!.grammarCopyBrck; + case 'Art': + return L10n.of(context)!.grammarCopyArt; + case 'Sing': + return L10n.of(context)!.grammarCopySing; + case 'Masc': + return L10n.of(context)!.grammarCopyMasc; + case 'Mod': + return L10n.of(context)!.grammarCopyMod; + case 'Adverbial': + return L10n.of(context)!.grammarCopyAdverbial; + case 'Peri': + return L10n.of(context)!.grammarCopyPeri; + case 'Digit': + return L10n.of(context)!.grammarCopyDigit; + case 'Not_proper': + return L10n.of(context)!.grammarCopyNot_proper; + case 'Card': + return L10n.of(context)!.grammarCopyCard; + case 'Prop': + return L10n.of(context)!.grammarCopyProp; + case 'Dash': + return L10n.of(context)!.grammarCopyDash; + case 'Yes': + return L10n.of(context)!.grammarCopyYes; + case 'Semi': + return L10n.of(context)!.grammarCopySemi; + case 'Comm': + return L10n.of(context)!.grammarCopyComm; + case 'Cnd': + return L10n.of(context)!.grammarCopyCnd; + case 'Int,Rel': + return L10n.of(context)!.grammarCopyIntRel; + case 'Acc': + return L10n.of(context)!.grammarCopyAcc; + case 'Part': + return L10n.of(context)! + .grammarCopyPartTag; // To avoid conflict with 'PART' POS + case 'Int': + return L10n.of(context)!.grammarCopyInt; + case 'Past': + return L10n.of(context)!.grammarCopyPast; + case 'Sup': + return L10n.of(context)!.grammarCopySup; + case 'Colo': + return L10n.of(context)!.grammarCopyColo; + case '3': + return L10n.of(context)!.grammarCopy3; + case 'Plur': + return L10n.of(context)!.grammarCopyPlur; + case 'Npr': + return L10n.of(context)!.grammarCopyNpr; + case 'Interrogative': + return L10n.of(context)!.grammarCopyInterrogative; + case 'Infm': + return L10n.of(context)!.grammarCopyInfm; + case 'Tim': + return L10n.of(context)!.grammarCopyTim; + case 'Neg': + return L10n.of(context)!.grammarCopyNeg; + case 'Tot': + return L10n.of(context)!.grammarCopyTot; + case 'Adnomial': + return L10n.of(context)!.grammarCopyAdnomial; + case 'Prog': + return L10n.of(context)!.grammarCopyProg; + case 'Sub': + return L10n.of(context)!.grammarCopySub; + case 'Complementive': + return L10n.of(context)!.grammarCopyComplementive; + case 'Nom': + return L10n.of(context)!.grammarCopyNom; + case 'Fut': + return L10n.of(context)!.grammarCopyFut; + case 'Dat': + return L10n.of(context)!.grammarCopyDat; + case 'Pres': + return L10n.of(context)!.grammarCopyPres; + case 'Neut': + return L10n.of(context)!.grammarCopyNeut; + case 'Rel': + return L10n.of(context)!.grammarCopyRel; + case 'Final_ending': + return L10n.of(context)!.grammarCopyFinal_ending; + case 'Dem': + return L10n.of(context)!.grammarCopyDem; + case 'Pre': + return L10n.of(context)!.grammarCopyPre; + case 'Fin': + return L10n.of(context)!.grammarCopyFin; + case 'Pos': + return L10n.of(context)!.grammarCopyPos; + case 'Quot': + return L10n.of(context)!.grammarCopyQuot; + case 'Ger': + return L10n.of(context)!.grammarCopyGer; + case 'Pass': + return L10n.of(context)!.grammarCopyPass; + case 'Gen': + return L10n.of(context)!.grammarCopyGen; + case 'Prs': + return L10n.of(context)!.grammarCopyPrs; + case 'Def': + return L10n.of(context)!.grammarCopyDef; + case 'Ord': + return L10n.of(context)!.grammarCopyOrd; + case 'Ins': + return L10n.of(context)!.grammarCopyIns; + case 'Acc,Dat': + return L10n.of(context)!.grammarCopyAccDat; + case 'Inf': + return L10n.of(context)!.grammarCopyInf; + case 'Long': + return L10n.of(context)!.grammarCopyLong; + case 'Ind': + return L10n.of(context)!.grammarCopyInd; + case 'Cmp': + return L10n.of(context)!.grammarCopyCmp; + case 'Relative_case': + return L10n.of(context)!.grammarCopyRelative_case; + case 'Excl': + return L10n.of(context)!.grammarCopyExcl; + case '1': + return L10n.of(context)!.grammarCopy1; + case 'Ini': + return L10n.of(context)!.grammarCopyIni; + case 'Person': + return L10n.of(context)!.grammarCopyPerson; + case 'Foreign': + return L10n.of(context)!.grammarCopyForeign; + case 'Voice': + return L10n.of(context)!.grammarCopyVoice; + case 'VerbType': + return L10n.of(context)!.grammarCopyVerbType; + case 'Poss': + return L10n.of(context)!.grammarCopyPoss; + case 'PrepCase': + return L10n.of(context)!.grammarCopyPrepCase; + case 'NumType': + return L10n.of(context)!.grammarCopyNumType; + case 'NounType': + return L10n.of(context)!.grammarCopyNounType; + case 'Reflex': + return L10n.of(context)!.grammarCopyReflex; + case 'PronType': + return L10n.of(context)!.grammarCopyPronType; + case 'PunctSide': + return L10n.of(context)!.grammarCopyPunctSide; + case 'VerbForm': + return L10n.of(context)!.grammarCopyVerbForm; + case 'Gender': + return L10n.of(context)!.grammarCopyGender; + case 'Mood': + return L10n.of(context)!.grammarCopyMood; + case 'Aspect': + return L10n.of(context)!.grammarCopyAspect; + case 'PunctType': + return L10n.of(context)!.grammarCopyPunctType; + case 'Tense': + return L10n.of(context)!.grammarCopyTense; + case 'Degree': + return L10n.of(context)!.grammarCopyDegree; + case 'Polite': + return L10n.of(context)!.grammarCopyPolite; + case 'AdvType': + return L10n.of(context)!.grammarCopyAdvType; + case 'Number': + return L10n.of(context)!.grammarCopyNumber; + case 'ConjType': + return L10n.of(context)!.grammarCopyConjType; + case 'Polarity': + return L10n.of(context)!.grammarCopyPolarity; + case 'Number[psor]': + return L10n.of(context)!.grammarCopyNumberPsor; + case 'Case': + return L10n.of(context)!.grammarCopyCase; + case 'Definite': + return L10n.of(context)!.grammarCopyDefinite; + case 'NumForm': + return L10n.of(context)!.grammarCopyNumForm; + // Handle empty tag + case '': + ErrorHandler.logError( + e: Exception('Empty tag'), + m: 'Empty tag in getGrammarCopy', + data: { + 'context': context, + }, + ); + return L10n.of(context)!.grammarCopyUnknown; + default: + debugger(when: kDebugMode); + ErrorHandler.logError( + e: Exception('Need to add copy for $tag to intl_en.arb'), + m: 'Need to add copy for $tag to intl_en.arb', + data: { + 'tag': tag, + 'context': context, + }, + ); + return tag; // Fallback to the tag itself if no match is found + } +} diff --git a/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart b/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart index 321795e24..9dcc7b06b 100644 --- a/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart +++ b/lib/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart @@ -1,6 +1,8 @@ import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; import 'package:fluffychat/pangea/enum/progress_indicators_enum.dart'; import 'package:fluffychat/pangea/models/analytics/construct_list_model.dart'; +import 'package:fluffychat/pangea/utils/get_grammar_copy.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -47,7 +49,13 @@ class AnalyticsPopup extends StatelessWidget { child: ListTile( onTap: () {}, title: Text( - constructsModel.constructList[index].lemma, + constructsModel.type == ConstructTypeEnum.morph + ? getGrammarCopy( + constructsModel + .constructList[index].lemma, + context, + ) + : constructsModel.constructList[index].lemma, ), subtitle: LinearProgressIndicator( value: diff --git a/lib/pangea/widgets/content_issue_button.dart b/lib/pangea/widgets/content_issue_button.dart index 7df2565c0..053d05f75 100644 --- a/lib/pangea/widgets/content_issue_button.dart +++ b/lib/pangea/widgets/content_issue_button.dart @@ -36,21 +36,20 @@ class ContentIssueButton extends StatelessWidget { L10n.of(context)!.reportContentIssueTitle, textAlign: TextAlign.center, ), - content: Container( - constraints: const BoxConstraints(maxWidth: 300), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const BotFace( - width: 60, - expression: BotExpression.addled, - ), - const SizedBox(height: 10), - Text(L10n.of(context)!.reportContentIssueDescription), - const SizedBox(height: 10), - SizedBox( - width: double.infinity, - child: TextField( + content: SingleChildScrollView( + child: Container( + constraints: const BoxConstraints(maxWidth: 300), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const BotFace( + width: 60, + expression: BotExpression.addled, + ), + const SizedBox(height: 10), + Text(L10n.of(context)!.reportContentIssueDescription), + const SizedBox(height: 10), + TextField( controller: feedbackController, decoration: InputDecoration( labelText: L10n.of(context)!.feedback, @@ -58,8 +57,8 @@ class ContentIssueButton extends StatelessWidget { ), maxLines: 4, ), - ), - ], + ], + ), ), ), actions: [ diff --git a/lib/pangea/widgets/practice_activity/practice_activity_card.dart b/lib/pangea/widgets/practice_activity/practice_activity_card.dart index 442b1cf64..7e80e2aaa 100644 --- a/lib/pangea/widgets/practice_activity/practice_activity_card.dart +++ b/lib/pangea/widgets/practice_activity/practice_activity_card.dart @@ -231,10 +231,6 @@ class MessagePracticeActivityCardState extends State { return; } - // clear the current activity and record - currentActivity = null; - currentCompletionRecord = null; - _fetchNewActivity( ActivityQualityFeedback( feedbackText: feedback, diff --git a/lib/utils/show_update_snackbar.dart b/lib/utils/show_update_snackbar.dart index eece3b4fb..a7ba4ce05 100644 --- a/lib/utils/show_update_snackbar.dart +++ b/lib/utils/show_update_snackbar.dart @@ -18,7 +18,12 @@ abstract class UpdateNotifier { ScaffoldFeatureController? controller; controller = scaffoldMessenger.showSnackBar( SnackBar( - duration: const Duration(seconds: 30), + duration: const Duration( + // #Pangea + // seconds: 30, + seconds: 5, + // Pangea# + ), content: Row( children: [ IconButton( diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index bd4cf0a66..b4271213f 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -1,8 +1,9 @@ import 'dart:async'; import 'package:adaptive_dialog/adaptive_dialog.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart'; import 'package:fluffychat/pangea/utils/download_chat.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; @@ -18,7 +19,6 @@ enum ChatPopupMenuActions { leave, search, // #Pangea - archive, downloadTxt, downloadCsv, downloadXlsx, @@ -118,25 +118,6 @@ class ChatSettingsPopupMenuState extends State { context.go('/rooms/${widget.room.id}/search'); break; // #Pangea - case ChatPopupMenuActions.archive: - final confirmed = await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.ok, - cancelLabel: L10n.of(context)!.cancel, - message: L10n.of(context)!.archiveRoomDescription, - ); - if (confirmed == OkCancelResult.ok) { - final success = await showFutureLoadingDialog( - context: context, - future: () => widget.room.archive(), - ); - if (success.error == null) { - context.go('/rooms'); - } - } - break; case ChatPopupMenuActions.downloadTxt: showFutureLoadingDialog( context: context, @@ -171,7 +152,30 @@ class ChatSettingsPopupMenuState extends State { ); break; case ChatPopupMenuActions.learningSettings: - context.go('/rooms/settings/learning'); + showDialog( + context: context, + builder: (c) { + return kIsWeb + ? Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 600, + maxHeight: 600, + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(20.0), + child: const SettingsLearning(isPopup: true), + ), + ), + ) + : Dialog.fullscreen( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 600), + child: const SettingsLearning(isPopup: true), + ), + ); + }, + ); break; // Pangea# } @@ -246,18 +250,6 @@ class ChatSettingsPopupMenuState extends State { ), ), // #Pangea - if (!widget.room.isArchived) - if (widget.room.isRoomAdmin) - PopupMenuItem( - value: ChatPopupMenuActions.archive, - child: Row( - children: [ - const Icon(Icons.archive_outlined), - const SizedBox(width: 12), - Text(L10n.of(context)!.archive), - ], - ), - ), PopupMenuItem( value: ChatPopupMenuActions.downloadTxt, child: Row( diff --git a/pubspec.yaml b/pubspec.yaml index 173fef435..39a7e9700 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+3540 +version: 1.21.5+3541 environment: sdk: ">=3.0.0 <4.0.0" @@ -49,7 +49,7 @@ dependencies: flutter_olm: 1.3.2 # Keep in sync with scripts/prepare-web.sh ! 1.4.0 does currently not build on Android flutter_openssl_crypto: ^0.3.0 flutter_ringtone_player: ^4.0.0+2 - flutter_secure_storage: ^9.0.0 + flutter_secure_storage: ^9.2.2 flutter_shortcuts: git: https://github.com/krille-chan/flutter_shortcuts.git flutter_typeahead: ^5.2.0