Merge branch 'main' into 737-private-class-code
This commit is contained in:
commit
6ea1b94a70
15 changed files with 514 additions and 162 deletions
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<String> 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<String>(
|
||||
future: getAppVersion(context),
|
||||
FutureBuilder<PackageInfo>(
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ extension RoomInformationRoomExtension on Room {
|
|||
);
|
||||
}
|
||||
|
||||
Future<bool> get _isBotDM async => botOptions?.mode == BotMode.direct;
|
||||
Future<bool> get _isBotDM async => botOptions?.mode == BotMode.directChat;
|
||||
|
||||
bool get _isLocked {
|
||||
if (isDirectChat) return false;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
// }),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
267
lib/pangea/utils/get_grammar_copy.dart
Normal file
267
lib/pangea/utils/get_grammar_copy.dart
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -231,10 +231,6 @@ class MessagePracticeActivityCardState extends State<PracticeActivityCard> {
|
|||
return;
|
||||
}
|
||||
|
||||
// clear the current activity and record
|
||||
currentActivity = null;
|
||||
currentCompletionRecord = null;
|
||||
|
||||
_fetchNewActivity(
|
||||
ActivityQualityFeedback(
|
||||
feedbackText: feedback,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<ChatSettingsPopupMenu> {
|
|||
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<ChatSettingsPopupMenu> {
|
|||
);
|
||||
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<ChatSettingsPopupMenu> {
|
|||
),
|
||||
),
|
||||
// #Pangea
|
||||
if (!widget.room.isArchived)
|
||||
if (widget.room.isRoomAdmin)
|
||||
PopupMenuItem<ChatPopupMenuActions>(
|
||||
value: ChatPopupMenuActions.archive,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.archive_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context)!.archive),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem<ChatPopupMenuActions>(
|
||||
value: ChatPopupMenuActions.downloadTxt,
|
||||
child: Row(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue