From a82f0e5c7a2fce6cdd3a8e2a098dd5b1552c244a Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 4 Jan 2024 16:04:53 -0500 Subject: [PATCH 1/7] fix for loading after joining chat in space view --- lib/pages/chat_list/space_view.dart | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 3aff52a5e..1c3de7485 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -234,6 +234,7 @@ class _SpaceViewState extends State { _refresh(); } + // @override @override void dispose() { super.dispose(); @@ -330,7 +331,17 @@ class _SpaceViewState extends State { // #Pangea void refreshOnUpdate(SyncUpdate event) { - if (event.isMembershipUpdate(Matrix.of(context).client.userID!) || + /* refresh on leave, invite, and space child update + not join events, because there's already a listener on + onTapSpaceChild, and they interfere with each other */ + if (event.isMembershipUpdateByType( + Membership.leave, + Matrix.of(context).client.userID!, + ) || + event.isMembershipUpdateByType( + Membership.invite, + Matrix.of(context).client.userID!, + ) || event.isSpaceChildUpdate(activeSpaceId)) { _refresh(); } From cfa84051c881ba21515f38ed35ec26d79efe49c3 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 4 Jan 2024 16:08:55 -0500 Subject: [PATCH 2/7] fix for innvite dialog not being dismissed after accepting --- .../utils/chat_list_handle_space_tap.dart | 113 +++++++----------- 1 file changed, 43 insertions(+), 70 deletions(-) diff --git a/lib/pangea/utils/chat_list_handle_space_tap.dart b/lib/pangea/utils/chat_list_handle_space_tap.dart index 4ddb76129..b2c74ccbd 100644 --- a/lib/pangea/utils/chat_list_handle_space_tap.dart +++ b/lib/pangea/utils/chat_list_handle_space_tap.dart @@ -1,13 +1,13 @@ +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:fluffychat/pages/chat_list/chat_list.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.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'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pages/chat_list/chat_list.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; -import 'package:fluffychat/widgets/matrix.dart'; import 'error_handler.dart'; // ignore: curly_braces_in_flow_control_structures @@ -43,74 +43,47 @@ void chatListHandleSpaceTap( //if accepted, setActiveSpaceAndCloseChat() //if rejected, leave space // use standard alert diolog, not cupertino - void showAlertDialog(BuildContext context) { - // set up the AlertDialog - final AlertDialog alert = AlertDialog( - title: Text(L10n.of(context)!.youreInvited), - content: Text( - space.isSpace - ? L10n.of(context)! - .invitedToClassOrExchange(space.name, space.creatorId ?? "???") - : L10n.of(context)! - .invitedToChat(space.name, space.creatorId ?? "???"), - ), - actions: [ - TextButton( - onPressed: () => showFutureLoadingDialog( - context: context, - future: () async { - await space.leave(); - //show snackbar message that you've left - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.declinedInvitation), - duration: const Duration(seconds: 3), - ), - ); - Navigator.of(context).pop(); - }, - onError: (exception) { - ErrorHandler.logError(e: exception); - Navigator.of(context).pop(); - return exception.toString(); - }, - ), - child: Text(L10n.of(context)!.decline), - ), - TextButton( - onPressed: () => showFutureLoadingDialog( - context: context, - future: () async { - await space.join(); - setActiveSpaceAndCloseChat(); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.acceptedInvitation), - duration: const Duration(seconds: 3), - ), - ); - context.go( - '/rooms/join_exchange/${controller.activeSpaceId}', - ); - }, - onError: (exception) { - ErrorHandler.logError(e: exception); - Navigator.of(context).pop(); - return exception.toString(); - }, - ), - child: Text(L10n.of(context)!.accept), - ), - ], + Future showAlertDialog(BuildContext context) async { + final acceptInvite = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context)!.youreInvited, + message: space.isSpace + ? L10n.of(context)! + .invitedToClassOrExchange(space.name, space.creatorId ?? "???") + : L10n.of(context)! + .invitedToChat(space.name, space.creatorId ?? "???"), + okLabel: L10n.of(context)!.accept, + cancelLabel: L10n.of(context)!.decline, ); - // show the dialog - showDialog( - context: context, - builder: (BuildContext context) { - return alert; - }, - ); + if (acceptInvite == OkCancelResult.ok) { + await showFutureLoadingDialog( + context: context, + future: () async { + await space.join(); + setActiveSpaceAndCloseChat(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.acceptedInvitation), + duration: const Duration(seconds: 3), + ), + ); + if (space.isExchange) { + context.go( + '/rooms/join_exchange/${controller.activeSpaceId}', + ); + } + }, + ); + } else { + await space.leave(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.declinedInvitation), + duration: const Duration(seconds: 3), + ), + ); + } } switch (space.membership) { From 62191a95846abed235ebc0eeef8de0f9bb6cdad9 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Thu, 4 Jan 2024 16:10:02 -0500 Subject: [PATCH 3/7] fix to ensure that new space class/exchange toggles always work --- lib/pages/new_space/new_space.dart | 40 ++++++------------- lib/pages/new_space/new_space_view.dart | 5 ++- .../widgets/class/add_space_toggles.dart | 20 +++++----- 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/lib/pages/new_space/new_space.dart b/lib/pages/new_space/new_space.dart index 2ff854e2c..112519238 100644 --- a/lib/pages/new_space/new_space.dart +++ b/lib/pages/new_space/new_space.dart @@ -1,14 +1,5 @@ import 'dart:developer'; -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'; -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart' as sdk; -import 'package:matrix/matrix.dart'; - import 'package:fluffychat/pages/new_space/new_space_view.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; @@ -22,6 +13,13 @@ import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; import 'package:fluffychat/pangea/widgets/space/class_settings.dart'; import 'package:fluffychat/widgets/matrix.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'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart' as sdk; +import 'package:matrix/matrix.dart'; class NewSpace extends StatefulWidget { const NewSpace({super.key}); @@ -46,18 +44,6 @@ class NewSpaceController extends State { // #Pangea bool newClassMode = true; - //in initState, set newClassMode to true if parameter "newClass" is true - //use Vrouter - @override - void initState() { - super.initState(); - Future.delayed(Duration.zero, () { - newClassMode = - GoRouterState.of(context).pathParameters['newexchange'] != 'exchange'; - setState(() {}); - }); - } - List get initialState { final events = []; @@ -225,13 +211,13 @@ class NewSpaceController extends State { // Pangea# } + @override // #Pangea - //toggle newClassMode - void toggleClassMode(bool newValue) { - setState(() => newClassMode = newValue); + // Widget build(BuildContext context) => NewSpaceView(this); + Widget build(BuildContext context) { + newClassMode = + GoRouterState.of(context).pathParameters['newexchange'] != 'exchange'; + return NewSpaceView(this); } // Pangea# - - @override - Widget build(BuildContext context) => NewSpaceView(this); } diff --git a/lib/pages/new_space/new_space_view.dart b/lib/pages/new_space/new_space_view.dart index 11cb9a542..fd9f861d1 100644 --- a/lib/pages/new_space/new_space_view.dart +++ b/lib/pages/new_space/new_space_view.dart @@ -10,6 +10,7 @@ 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:go_router/go_router.dart'; import 'new_space.dart'; @@ -40,14 +41,14 @@ class NewSpaceView extends StatelessWidget { selectedIcon: const Icon(Icons.class_), color: controller.newClassMode ? activeColor : null, isSelected: controller.newClassMode, - onPressed: () => controller.toggleClassMode(true), + onPressed: () => context.go('/rooms/newspace'), ), IconButton( icon: const Icon(Icons.connecting_airports), selectedIcon: const Icon(Icons.connecting_airports), color: !controller.newClassMode ? activeColor : null, isSelected: !controller.newClassMode, - onPressed: () => controller.toggleClassMode(false), + onPressed: () => context.go('/rooms/newspace/exchange'), ), ], // title: Text(L10n.of(context)!.createNewSpace), diff --git a/lib/pangea/widgets/class/add_space_toggles.dart b/lib/pangea/widgets/class/add_space_toggles.dart index 653fa339d..4ee19ffbb 100644 --- a/lib/pangea/widgets/class/add_space_toggles.dart +++ b/lib/pangea/widgets/class/add_space_toggles.dart @@ -1,13 +1,12 @@ -import 'package:flutter/material.dart'; - import 'package:collection/collection.dart'; +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; -import 'package:fluffychat/pangea/utils/error_handler.dart'; import '../../../widgets/matrix.dart'; import '../../utils/firebase_analytics.dart'; import 'add_class_and_invite.dart'; @@ -198,10 +197,13 @@ class AddToSpaceState extends State { title: Row( children: [ const SizedBox(width: 32), - Text( - L10n.of(context)!.suggestTo(possibleParentName), - style: TextStyle( - color: Theme.of(context).colorScheme.secondary, + Expanded( + child: Text( + L10n.of(context)!.suggestTo(possibleParentName), + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + ), + overflow: TextOverflow.ellipsis, ), ), ], From 1bddef6874a8b9e852c7a00c181f218aebca5352 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Fri, 5 Jan 2024 15:45:07 -0500 Subject: [PATCH 4/7] added pagination to find a convo partner page --- .../pages/find_partner/find_partner.dart | 97 +++++++++++++------ .../pages/find_partner/find_partner_view.dart | 51 +++++----- lib/pangea/repo/user_repo.dart | 12 +-- pubspec.lock | 4 +- pubspec.yaml | 2 +- 5 files changed, 101 insertions(+), 65 deletions(-) diff --git a/lib/pangea/pages/find_partner/find_partner.dart b/lib/pangea/pages/find_partner/find_partner.dart index 18fc71307..f2bd7e8c1 100644 --- a/lib/pangea/pages/find_partner/find_partner.dart +++ b/lib/pangea/pages/find_partner/find_partner.dart @@ -1,9 +1,10 @@ import 'dart:async'; -import 'package:flutter/material.dart'; - +import 'package:country_picker/country_picker.dart'; import 'package:fluffychat/pangea/models/language_model.dart'; import 'package:fluffychat/pangea/models/user_model.dart'; +import 'package:flutter/material.dart'; + import '../../../widgets/matrix.dart'; import '../../controllers/pangea_controller.dart'; import '../../models/user_profile_search_model.dart'; @@ -20,6 +21,7 @@ class FindPartner extends StatefulWidget { class FindPartnerController extends State { PangeaController pangeaController = MatrixState.pangeaController; + bool initialLoad = true; bool loading = false; String currentSearchTerm = ""; late LanguageModel targetLanguageSearch; @@ -28,12 +30,15 @@ class FindPartnerController extends State { String? flagEmoji; //PTODO - implement pagination - String? previousPage; + String? nextUrl = ""; + int nextPage = 1; Timer? coolDown; final List _userProfilesCache = []; + final scrollController = ScrollController(); + @override void initState() { targetLanguageSearch = pangeaController.languageController.userL1 ?? @@ -41,31 +46,29 @@ class FindPartnerController extends State { sourceLanguageSearch = pangeaController.languageController.userL2 ?? pangeaController.pLanguageStore.targetOptions[0]; - searchUserProfiles(); + scrollController.addListener(() { + if (scrollController.position.pixels == + scrollController.position.maxScrollExtent) { + searchUserProfiles(); + } + }); + + searchUserProfiles().then((_) => setState(() => initialLoad = false)); + super.initState(); } + @override + void dispose() { + scrollController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return FindPartnerView(this); } - // List get userProfiles => currentSearchTerm.isNotEmpty - // ? _userProfilesCache - // .where((p) => - // (p.fullName != null && p.fullName!.contains(currentSearchTerm)) || - // (p.pangeaUserId != null && - // p.pangeaUserId!.contains(currentSearchTerm)) || - // (p.sourceLanguage != null && - // p.sourceLanguage!.contains(currentSearchTerm)) || - // // (p.speaks != null && - // // p.speaks!.any((e) => e.contains(currentSearchTerm))) || - // (p.country != null && p.country!.contains(currentSearchTerm)) || - // // (p.interests != null && - // // p.interests!.any((e) => e.contains(currentSearchTerm)))) - // .toList() - // : _userProfilesCache; - List get userProfiles => _userProfilesCache.where((p) { return (p.targetLanguage != null && targetLanguageSearch.langCode == p.targetLanguage) && @@ -83,9 +86,9 @@ class FindPartnerController extends State { ); } - void searchUserProfiles() async { + Future searchUserProfiles() async { coolDown?.cancel(); - if (loading) return; + if (loading || nextUrl == null) return; setState(() => loading = true); final UserProfileSearchResponse response = @@ -94,15 +97,51 @@ class FindPartnerController extends State { targetLanguage: targetLanguageSearch.langCode, sourceLanguage: sourceLanguageSearch.langCode, country: countrySearch, - limit: 30, + limit: 15, + pageNumber: nextPage.toString(), + ); + + nextUrl = response.next; + nextPage++; + + final String? currentUserId = + pangeaController.userController.userModel?.profile?.pangeaUserId; + _userProfilesCache.addAll( + response.results.where( + (p) => + !_userProfilesCache.any( + (element) => p.pangeaUserId == element.pangeaUserId, + ) && + p.pangeaUserId != currentUserId, + ), ); - for (final p in response.results) { - if (!_userProfilesCache - .any((element) => p.pangeaUserId == element.pangeaUserId)) { - _userProfilesCache.add(p); - } - } setState(() => loading = false); } + + Future filterUserProfiles({ + LanguageModel? targetLanguage, + LanguageModel? sourceLanguage, + Country? country, + }) async { + if (country != null) { + if (country.name != "World Wide") { + countrySearch = country.displayNameNoCountryCode; + flagEmoji = country.flagEmoji; + } else { + countrySearch = null; + flagEmoji = null; + } + } + if (targetLanguage != null) { + targetLanguageSearch = targetLanguage; + } + if (sourceLanguage != null) { + sourceLanguageSearch = sourceLanguage; + } + nextPage = 1; + nextUrl = ""; + await searchUserProfiles(); + setState(() {}); + } } diff --git a/lib/pangea/pages/find_partner/find_partner_view.dart b/lib/pangea/pages/find_partner/find_partner_view.dart index bbb163a69..e404559ed 100644 --- a/lib/pangea/pages/find_partner/find_partner_view.dart +++ b/lib/pangea/pages/find_partner/find_partner_view.dart @@ -1,10 +1,4 @@ -import 'package:flutter/material.dart'; - import 'package:country_picker/country_picker.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart' as matrix; - import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pangea/models/user_model.dart'; import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart'; @@ -12,6 +6,11 @@ import 'package:fluffychat/pangea/widgets/common/pangea_logo_svg.dart'; import 'package:fluffychat/pangea/widgets/user_settings/p_language_dropdown.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart' as matrix; + import '../../../widgets/profile_bottom_sheet.dart'; import 'find_partner.dart'; @@ -80,15 +79,9 @@ class FindPartnerView extends StatelessWidget { context: context, showPhoneCode: false, onSelect: (Country country) { - if (country.name != "World Wide") { - controller.countrySearch = - country.displayNameNoCountryCode; - controller.flagEmoji = country.flagEmoji; - } else { - controller.countrySearch = null; - controller.flagEmoji = null; - } - controller.searchUserProfiles(); + controller.filterUserProfiles( + country: country, + ); }, ), ), @@ -97,16 +90,22 @@ class FindPartnerView extends StatelessWidget { ], ), ), - controller.loading + controller.initialLoad ? const ExpandedContainer(body: ListPlaceholder()) : controller.userProfiles.isNotEmpty ? ExpandedContainer( body: ListView.builder( - itemCount: controller.userProfiles.length, - itemBuilder: (context, i) => UserProfileEntry( - pangeaProfile: controller.userProfiles[i], - controller: controller, - ), + controller: controller.scrollController, + itemCount: controller.userProfiles.length + 1, + itemBuilder: (context, i) => i != + controller.userProfiles.length + ? UserProfileEntry( + pangeaProfile: controller.userProfiles[i], + controller: controller, + ) + : controller.loading + ? const CircularProgressIndicator.adaptive() + : const SizedBox.shrink(), ), ) : ExpandedContainer( @@ -160,7 +159,7 @@ class ProfileSearchTextField extends StatelessWidget { maxHeight: 48, minWidth: 48, ), - suffixIcon: controller.loading + suffixIcon: controller.initialLoad ? const CircularProgressIndicator.adaptive() : const Icon(Icons.search_outlined), contentPadding: const EdgeInsets.symmetric(horizontal: 16), @@ -225,10 +224,10 @@ class LanguageSelectionRow extends StatelessWidget { ? controller.pangeaController.pLanguageStore.baseOptions : controller.pangeaController.pLanguageStore.targetOptions, onChange: (language) { - isSource - ? controller.sourceLanguageSearch = language - : controller.targetLanguageSearch = language; - controller.searchUserProfiles(); + controller.filterUserProfiles( + sourceLanguage: isSource ? language : null, + targetLanguage: isSource ? null : language, + ); }, initialLanguage: isSource ? controller.sourceLanguageSearch diff --git a/lib/pangea/repo/user_repo.dart b/lib/pangea/repo/user_repo.dart index 452120962..76b4104fc 100644 --- a/lib/pangea/repo/user_repo.dart +++ b/lib/pangea/repo/user_repo.dart @@ -1,9 +1,9 @@ import 'dart:convert'; import 'dart:developer'; +import 'package:fluffychat/pangea/constants/model_keys.dart'; import 'package:http/http.dart'; -import 'package:fluffychat/pangea/constants/model_keys.dart'; import '../../widgets/matrix.dart'; import '../models/user_model.dart'; import '../models/user_profile_search_model.dart'; @@ -106,14 +106,12 @@ class PUserRepo { body[ModelKey.userSourceLanguage] = sourceLanguage; } if (country != null) body[ModelKey.userCountry] = country; - // if (speaks != null) body[ModelKey.userSpeaks] = speaks; - if (pageNumber != null) { - body["page_number"] = pageNumber; - } - body["limit"] = limit; + + final String searchUrl = + "${PApiUrls.searchUserProfiles}?limit=$limit${pageNumber != null ? '&page=$pageNumber' : ''}"; final Response res = await req.post( - url: PApiUrls.searchUserProfiles, + url: searchUrl, body: body, ); diff --git a/pubspec.lock b/pubspec.lock index c5c084469..c60c51ceb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -245,10 +245,10 @@ packages: dependency: "direct main" description: name: country_picker - sha256: "931454ceb75c7e1230ac5620bfe601a5a293b4436d8de8bf7fea776a05a9568c" + sha256: c578292d7d3ec3132c6634f9c7aab96528f74d61fd363073d5f5a8562bede732 url: "https://pub.dev" source: hosted - version: "2.0.22" + version: "2.0.23" cross_file: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8a788363b..b100ba398 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: chewie: ^1.7.1 collection: ^1.17.2 connectivity_plus: ^3.0.2 - country_picker: ^2.0.20 + country_picker: ^2.0.23 csv: ^5.0.2 cupertino_icons: any desktop_drop: ^0.4.4 From 5f3ee270a4b271ffea2aaa29fb4871b0e7575540 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 8 Jan 2024 15:22:27 -0500 Subject: [PATCH 5/7] minor UI fixes from mobile testing --- assets/l10n/intl_en.arb | 3 +- lib/pages/chat_details/chat_details_view.dart | 15 ++++--- .../invitation_selection.dart | 13 +++--- .../invitation_selection_view.dart | 20 ++++++--- .../p_class_widgets/room_rules_editor.dart | 36 ++++++++-------- .../pages/find_partner/find_partner_view.dart | 5 ++- .../widgets/class/add_space_toggles.dart | 2 +- lib/widgets/profile_bottom_sheet.dart | 41 ++++++++++++------- 8 files changed, 77 insertions(+), 58 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 793c97447..780db7e9d 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -3957,5 +3957,6 @@ "activateTrial": "Activate Trial", "inNoSpaces": "You are not a member of any classes or exchanges", "successfullySubscribed": "You have successfully subscribed!", - "clickToManageSubscription": "Click here to manage your subscription." + "clickToManageSubscription": "Click here to manage your subscription.", + "emptyInviteWarning": "Add this chat to a class or exchange to invite other users." } diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index ee14bda2d..94be46c57 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -1,10 +1,3 @@ -import 'package:flutter/material.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'; -import 'package:matrix/matrix.dart'; - import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/chat_details/chat_details.dart'; import 'package:fluffychat/pages/chat_details/participant_list_item.dart'; @@ -26,6 +19,11 @@ import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.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'; +import 'package:matrix/matrix.dart'; class ChatDetailsView extends StatelessWidget { final ChatDetailsController controller; @@ -459,7 +457,8 @@ class ChatDetailsView extends StatelessWidget { color: Theme.of(context).dividerColor, ), // #Pangea - if (room.canInvite) + if (room.canInvite && + (!room.isSpace || room.isRoomAdmin)) ListTile( title: Text( room.isSpace diff --git a/lib/pages/invitation_selection/invitation_selection.dart b/lib/pages/invitation_selection/invitation_selection.dart index 6736f099a..4811934eb 100644 --- a/lib/pages/invitation_selection/invitation_selection.dart +++ b/lib/pages/invitation_selection/invitation_selection.dart @@ -1,19 +1,17 @@ import 'dart:async'; -import 'package:flutter/material.dart'; - import 'package:adaptive_dialog/adaptive_dialog.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:matrix/matrix.dart'; - import 'package:fluffychat/pages/invitation_selection/invitation_selection_view.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; -import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:matrix/matrix.dart'; + import '../../utils/localized_exception_extension.dart'; //#Pangea @@ -165,7 +163,6 @@ class InvitationSelectionController extends State { ]), ), ]), - onError: (e) => ErrorHandler.logError(e: e, s: StackTrace.current), // Pangea# ); if (success.error == null) { diff --git a/lib/pages/invitation_selection/invitation_selection_view.dart b/lib/pages/invitation_selection/invitation_selection_view.dart index 5d5540084..bf3229515 100644 --- a/lib/pages/invitation_selection/invitation_selection_view.dart +++ b/lib/pages/invitation_selection/invitation_selection_view.dart @@ -1,12 +1,10 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:matrix/matrix.dart'; - import 'package:fluffychat/pages/invitation_selection/invitation_selection.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; class InvitationSelectionView extends StatelessWidget { final InvitationSelectionController controller; @@ -74,6 +72,18 @@ class InvitationSelectionView extends StatelessWidget { builder: (context, snapshot) { final participants = room.getParticipants().map((user) => user.id).toSet(); + if (controller.mode != InvitationSelectionMode.admin && + room.spaceParents.isEmpty) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: Center( + child: Text( + L10n.of(context)!.emptyInviteWarning, + textAlign: TextAlign.center, + ), + ), + ); + } return controller.foundProfiles.isNotEmpty ? ListView.builder( physics: const NeverScrollableScrollPhysics(), diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart index 9c7823e5b..56ab5c360 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart @@ -154,26 +154,22 @@ class RoomRulesState extends State { ), subtitle: Text(setting.toolDescription(context)), ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 120.0), - child: Slider( - value: rules.getToolSettings(setting).toDouble(), - onChanged: (value) { - updatePermission(() { - rules.setLanguageToolSetting( - setting, - value.toInt(), - ); - }); - }, - divisions: 2, - max: 2, - min: 0, - label: rules.languageToolPermissionsText( - context, - setting, - ), + Slider( + value: rules.getToolSettings(setting).toDouble(), + onChanged: (value) { + updatePermission(() { + rules.setLanguageToolSetting( + setting, + value.toInt(), + ); + }); + }, + divisions: 2, + max: 2, + min: 0, + label: rules.languageToolPermissionsText( + context, + setting, ), ), ], diff --git a/lib/pangea/pages/find_partner/find_partner_view.dart b/lib/pangea/pages/find_partner/find_partner_view.dart index e404559ed..afef95885 100644 --- a/lib/pangea/pages/find_partner/find_partner_view.dart +++ b/lib/pangea/pages/find_partner/find_partner_view.dart @@ -104,7 +104,10 @@ class FindPartnerView extends StatelessWidget { controller: controller, ) : controller.loading - ? const CircularProgressIndicator.adaptive() + ? const Center( + child: CircularProgressIndicator + .adaptive(), + ) : const SizedBox.shrink(), ), ) diff --git a/lib/pangea/widgets/class/add_space_toggles.dart b/lib/pangea/widgets/class/add_space_toggles.dart index 4ee19ffbb..9103bad16 100644 --- a/lib/pangea/widgets/class/add_space_toggles.dart +++ b/lib/pangea/widgets/class/add_space_toggles.dart @@ -70,7 +70,7 @@ class AddToSpaceState extends State { if (widget.activeSpaceId != null) { final activeSpace = Matrix.of(context).client.getRoomById(widget.activeSpaceId!); - if (activeSpace != null) { + if (activeSpace != null && activeSpace.canIAddSpaceChild(null)) { parents.add(SuggestionStatus(false, activeSpace)); } else { ErrorHandler.logError( diff --git a/lib/widgets/profile_bottom_sheet.dart b/lib/widgets/profile_bottom_sheet.dart index 3bfbb2029..c6dab9fbc 100644 --- a/lib/widgets/profile_bottom_sheet.dart +++ b/lib/widgets/profile_bottom_sheet.dart @@ -1,13 +1,11 @@ +import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.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'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/widgets/avatar.dart'; -import 'package:fluffychat/widgets/matrix.dart'; - class ProfileBottomSheet extends StatelessWidget { final String userId; final BuildContext outerContext; @@ -46,17 +44,32 @@ class ProfileBottomSheet extends StatelessWidget { leading: CloseButton( onPressed: Navigator.of(context, rootNavigator: false).pop, ), - title: ListTile( - contentPadding: const EdgeInsets.only(right: 16.0), - title: Text( - profile?.displayName ?? userId.localpart ?? userId, - style: const TextStyle(fontSize: 18), - ), - subtitle: Text( - userId, - style: const TextStyle(fontSize: 12), - ), + // #Pangea + // title: ListTile( + // contentPadding: const EdgeInsets.only(right: 16.0), + // title: Text( + // profile?.displayName ?? userId.localpart ?? userId, + // style: const TextStyle(fontSize: 18), + // ), + // subtitle: Text( + // userId, + // style: const TextStyle(fontSize: 12), + // ), + // ), + title: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + profile?.displayName ?? userId.localpart ?? userId, + style: const TextStyle(fontSize: 18), + ), + Text( + userId, + style: const TextStyle(fontSize: 12), + ), + ], ), + // Pangea# actions: [ Padding( padding: const EdgeInsets.all(8.0), From 9e061a31c536965f14d6eeda1eaa2770975119f5 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 8 Jan 2024 15:57:11 -0500 Subject: [PATCH 6/7] fix for iOS build --- ios/Runner/Info.plist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 546e02616..97f0234c4 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -45,6 +45,10 @@ LSRequiresIPhoneOS + + FLTEnableImpeller + + NSAppleMusicUsageDescription Play audio and voice messages in the app. NSBluetoothAlwaysUsageDescription From 2f7b8172a37e3f1de4648596eb7f3afc3913e4a7 Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 8 Jan 2024 16:10:19 -0500 Subject: [PATCH 7/7] spanish translations --- assets/l10n/intl_es.arb | 554 ++++++++++++++-------------------------- 1 file changed, 187 insertions(+), 367 deletions(-) diff --git a/assets/l10n/intl_es.arb b/assets/l10n/intl_es.arb index 630db9401..334cb1223 100644 --- a/assets/l10n/intl_es.arb +++ b/assets/l10n/intl_es.arb @@ -1527,29 +1527,29 @@ "type": "text", "placeholders": {} }, - "sender": "Remitente", + "sender": "", "@sender": {}, - "pinMessage": "Anclar al chat", + "pinMessage": "", "@pinMessage": {}, - "confirmEventUnpin": "¿Está seguro de desanclar definitivamente el mensaje?", + "confirmEventUnpin": "", "@confirmEventUnpin": {}, - "emojis": "Emojis", + "emojis": "", "@emojis": {}, - "placeCall": "Hacer llamada", + "placeCall": "", "@placeCall": {}, "voiceCall": "Llamada de voz", "@voiceCall": {}, - "unsupportedAndroidVersion": "Versión de Android no compatible", + "unsupportedAndroidVersion": "", "@unsupportedAndroidVersion": {}, - "unsupportedAndroidVersionLong": "Esta función requiere una versión más reciente de Android. Verifique si hay actualizaciones o soporte de Lineage OS.", + "unsupportedAndroidVersionLong": "", "@unsupportedAndroidVersionLong": {}, - "videoCallsBetaWarning": "Tenga en cuenta que las videollamadas se encuentran actualmente en versión beta. Es posible que no funcionen como se esperaba o que no funcionen en todas las plataformas.", + "videoCallsBetaWarning": "", "@videoCallsBetaWarning": {}, - "experimentalVideoCalls": "Videollamadas experimentales", + "experimentalVideoCalls": "", "@experimentalVideoCalls": {}, - "indexedDbErrorTitle": "Problemas del modo privado", + "indexedDbErrorTitle": "", "@indexedDbErrorTitle": {}, - "indexedDbErrorLong": "Desafortunadamente, el almacenamiento de mensajes no está habilitado en modo privado de forma predeterminada.\nVisite\n - about:config\n - establezca dom.indexedDB.privateBrowsing.enabled en verdadero\nDe lo contrario, no es posible ejecutar FluffyChat.", + "indexedDbErrorLong": "", "@indexedDbErrorLong": {}, "reactedWith": "{sender} reaccionó con {reaction}", "@reactedWith": { @@ -1559,7 +1559,7 @@ "reaction": {} } }, - "switchToAccount": "Cambiar a la cuenta {number}", + "switchToAccount": "", "@switchToAccount": { "type": "number", "placeholders": { @@ -2207,7 +2207,7 @@ "type": "text", "placeholders": {} }, - "enterASpacepName": "Ingrese nombre de espacio", + "enterASpacepName": "Introduzca un nombre", "@enterASpacepName": {}, "ignore": "Bloquear", "@ignore": { @@ -3262,7 +3262,7 @@ "timeOfLastMessage": "Hora del último mensaje enviado", "totalMessages": "Mensajes totales enviados", "changeDateRange": "Cambiar rango de fechas", - "doNotShowAgain": "No mostrar de nuevo.", + "doNotShowAgain": "", "l1SpanAndGrammarTitle": "Fuera del idioma de destino", "l1SpanAndGrammarDesc": "Esto podría estar en su idioma base o podría ser un error gramatical.", "allCorrect": "¡Así es como lo diría yo! ¡Muy bien!", @@ -3323,7 +3323,7 @@ "waTooltip": "Uso de L2 sin asistencia", "unTooltip": "Otra", "interactiveGrammarSliderHeader": "Asistencia gramatical", - "allRooms": "Todos los chats grupales", + "allRooms": "", "@allRooms": { "type": "text", "placeholders": {} @@ -3338,26 +3338,26 @@ "igcIsDisabled": "La asistencia gramatical está deshabilitada.", "goToLearningSettings": "Vaya a Ajustes de aprendizaje.", "learningSettings": "Ajustes de aprendizaje", - "report": "Reportar", - "reportErrorDescription": "Oh, no. Algo salió mal. Por favor, inténtelo de nuevo más tarde. Si lo desea, puede reportar el error a los desarrolladores.", + "report": "", + "reportErrorDescription": "", "clearAll": "¿Borrar todas las palabras?", - "jump": "Saltar", - "openLinkInBrowser": "Abrir enlace en el navegador.", - "jumpToLastReadMessage": "Saltar al último mensaje leído.", - "readUpToHere": "Leído hasta aquí.", - "newSpaceDescription": "Espacios le permite consolidar sus chats y crear comunidades privadas o públicas.", - "encryptThisChat": "Encriptar este chat", - "endToEndEncryption": "Encriptado de fin a fin", - "disableEncryptionWarning": "Por razones de seguridad, no puede deshabilitar el cifrado en un chat, donde se ha habilitado antes.", - "sorryThatsNotPossible": "Discupla... eso no es posible", - "deviceKeys": "Claves del dispositivo:", - "letsStart": "¡Empecemos!", - "enterInviteLinkOrMatrixId": "Ingrese el enlace de invitación o ID de Matrix...", - "reopenChat": "Reabrir chat", - "noBackupWarning": "¡No olvida su contraseña!", - "noOtherDevicesFound": "No se encontraron otros dispositivos", - "fileIsTooBigForServer": "El servidor informa que el archivo es demasiado grande para enviarlo.", - "fileHasBeenSavedAt": "Se ha guardado el archivo en {path}", + "jump": "", + "openLinkInBrowser": "", + "jumpToLastReadMessage": "", + "readUpToHere": "", + "newSpaceDescription": "", + "encryptThisChat": "", + "endToEndEncryption": "", + "disableEncryptionWarning": "", + "sorryThatsNotPossible": "", + "deviceKeys": "", + "letsStart": "", + "enterInviteLinkOrMatrixId": "", + "reopenChat": "", + "noBackupWarning": "", + "noOtherDevicesFound": "", + "fileIsTooBigForServer": "", + "fileHasBeenSavedAt": "", "@fileHasBeenSavedAt": { "type": "text", "placeholders": { @@ -3413,37 +3413,37 @@ "type": "text", "placeholders": {} }, - "user": "Usuario", + "user": "", "@user": {}, - "custom": "personalizado", + "custom": "", "@custom": {}, - "foregroundServiceRunning": "Esta notificación aparece cuando se está ejecutando el servicio en primer plano.", + "foregroundServiceRunning": "", "@foregroundServiceRunning": {}, - "screenSharingTitle": "compartiendo pantalla", + "screenSharingTitle": "", "@screenSharingTitle": {}, - "screenSharingDetail": "Está compartiendo su pantalla en FluffyChat.", + "screenSharingDetail": "", "@screenSharingDetail": {}, - "callingPermissions": "Permisos de llamada", + "callingPermissions": "", "@callingPermissions": {}, - "callingAccount": "Llamando cuenta", + "callingAccount": "", "@callingAccount": {}, - "callingAccountDetails": "Permite que FluffyChat use la aplicación de marcación nativa de Android.", + "callingAccountDetails": "", "@callingAccountDetails": {}, - "appearOnTop": "Aparecer arriba", + "appearOnTop": "", "@appearOnTop": {}, - "appearOnTopDetails": "Permite que la aplicación aparezca en la parte superior (no es necesario si ya tiene configurado Fluffychat como cuenta de llamadas).", + "appearOnTopDetails": "", "@appearOnTopDetails": {}, "otherCallingPermissions": "Micrófono, cámara y otros permisos de FluffyChat", "@otherCallingPermissions": {}, - "whyIsThisMessageEncrypted": "¿Por qué este mensaje no se puede leer?", + "whyIsThisMessageEncrypted": "", "@whyIsThisMessageEncrypted": {}, - "noKeyForThisMessage": "Esto puede suceder si el mensaje se envió antes de que haya iniciado sesión en su cuenta en este dispositivo.\n\nTambién es posible que el remitente haya bloqueado su dispositivo o que algo haya fallado con la conexión a Internet.\n\n¿Puede leer el mensaje en otra sesión? ¡Entonces puede transferir el mensaje desde allí! Vaya a Configuración > Dispositivos y asegúrese de que sus dispositivos se hayan verificado entre sí. La próxima vez que abra la sala y ambas sesiones estén en primer plano, las claves se transmitirán automáticamente.\n\n¿No desea perder las claves al cerrar sesión o al cambiar de dispositivo? Asegúrese de haber habilitado la copia de seguridad del chat en la configuración.", + "noKeyForThisMessage": "", "@noKeyForThisMessage": {}, "newGroup": "Nuevo chat", "@newGroup": {}, - "enterRoom": "Unirse al chat", + "enterRoom": "", "@enterRoom": {}, - "numChats": "{number} chats", + "numChats": "", "@numChats": { "type": "number", "placeholders": { @@ -3457,52 +3457,52 @@ "number": {} } }, - "hideUnimportantStateEvents": "Ocultar eventos de estado sin importancia", - "wasDirectChatDisplayName": "Chat vacío (era {oldDisplayName})", + "hideUnimportantStateEvents": "", + "wasDirectChatDisplayName": "", "@wasDirectChatDisplayName": { "type": "text", "placeholders": { "oldDisplayName": {} } }, - "startFirstChat": "Empezar su primer chat", + "startFirstChat": "", "nextAccount": "Próxima cuenta", "@nextAccount": {}, "previousAccount": "Cuenta anterior", "@previousAccount": {}, - "editWidgets": "Editar artilugios", + "editWidgets": "", "@editWidgets": {}, - "addWidget": "Agregar artilugio", + "addWidget": "", "@addWidget": {}, - "widgetVideo": "Video", + "widgetVideo": "", "@widgetVideo": {}, "widgetEtherpad": "Nota de texto", "@widgetEtherpad": {}, "widgetJitsi": "Jitsi Meet", "@widgetJitsi": {}, - "widgetCustom": "Personalizado", + "widgetCustom": "", "@widgetCustom": {}, "widgetName": "Nombre", "@widgetName": {}, "widgetUrlError": "Esto no es un enlace válido.", "@widgetUrlError": {}, - "widgetNameError": "Proporcione un nombre para mostrar.", + "widgetNameError": "", "@widgetNameError": {}, - "errorAddingWidget": "Error an agregar el artilugio.", + "errorAddingWidget": "", "@errorAddingWidget": {}, "youRejectedTheInvitation": "Rechazó la invitación.", "@youRejectedTheInvitation": {}, - "youJoinedTheChat": "Se unió al chat.", + "youJoinedTheChat": "", "@youJoinedTheChat": {}, - "youAcceptedTheInvitation": "👍 Aceptó la invitación.", + "youAcceptedTheInvitation": "👍 Aceptaste la invitación", "@youAcceptedTheInvitation": {}, - "youBannedUser": "Bloqueó {user}", + "youBannedUser": "", "@youBannedUser": { "placeholders": { "user": {} } }, - "youHaveWithdrawnTheInvitationFor": "You have withdrawn the invitation for {user}", + "youHaveWithdrawnTheInvitationFor": "", "@youHaveWithdrawnTheInvitationFor": { "placeholders": { "user": {} @@ -3514,54 +3514,50 @@ "user": {} } }, - "youAcceptedTheInvitation": "👍 Aceptaste la invitación", - "@youAcceptedTheInvitation": {}, - "widgetEtherpad": "Nota de texto", - "@widgetEtherpad": {}, - "commandHint_cuddle": "Mandar una carantoña", + "commandHint_cuddle": "Enviar un arrunche.", "@commandHint_cuddle": {}, - "supposedMxid": "Esto debería ser {mxid}", - "youInvitedUser": "📩 Invitó {user}", + "supposedMxid": "Esto debe ser {mxid}", + "youInvitedUser": "", "@youInvitedUser": { "placeholders": { "user": {} } }, - "youKicked": "👞 Eliminó {user}", + "youKicked": "", "@youKicked": { "placeholders": { "user": {} } }, - "youKickedAndBanned": "🙅 Eliminó y bloqueó {user}", + "youKickedAndBanned": "", "@youKickedAndBanned": { "placeholders": { "user": {} } }, - "youUnbannedUser": "Desbloqueó {user}", + "youUnbannedUser": "", "@youUnbannedUser": { "placeholders": { "user": {} } }, - "noEmailWarning": "Por favor, introduzca una dirección de correo electrónico válida. De lo contrario, no podrá restablecer su contraseña. Si no quiere, toque de nuevo el botón para continuar.", + "noEmailWarning": "", "@noEmailWarning": {}, "stories": "Historias", "@stories": {}, "users": "Usuarios", "@users": {}, - "unlockOldMessages": "Desbloquear mensajes viejos.", + "unlockOldMessages": "", "@unlockOldMessages": {}, - "storeInSecureStorageDescription": "Guarde la clave de recuperación en el almacenamiento seguro de este dispositivo.", + "storeInSecureStorageDescription": "", "@storeInSecureStorageDescription": {}, - "saveKeyManuallyDescription": "Guarde esta clave manualmente activando el cuadro de diálogo compartido del sistema o el portapapeles.", + "saveKeyManuallyDescription": "", "@saveKeyManuallyDescription": {}, - "storeInAndroidKeystore": "Guardar en Android KeyStore", + "storeInAndroidKeystore": "", "@storeInAndroidKeystore": {}, - "storeInAppleKeyChain": "Guardar en Apple Acceso de Llaveros", + "storeInAppleKeyChain": "", "@storeInAppleKeyChain": {}, - "storeSecurlyOnThisDevice": "Almacenar de forma segura en este dispositivo", + "storeSecurlyOnThisDevice": "", "@storeSecurlyOnThisDevice": {}, "countFiles": "{count} archivos", "@countFiles": { @@ -3571,24 +3567,22 @@ }, "confirmMatrixId": "Confirme su ID de Matrix para eliminar su cuenta.", "@confirmMatrixId": {}, - "supposedMxid": "Esto debe ser {mxid}", "@supposedMxid": { "type": "text", "placeholders": { "mxid": {} } }, - "commandHint_googly": "Enviar unos ojos saltones.", - "commandHint_cuddle": "Enviar un arrunche.", + "commandHint_googly": "", "commandHint_hug": "Enviar un abrazo.", - "googlyEyesContent": "{senderName} le manda ojos saltones.", + "googlyEyesContent": "", "@googlyEyesContent": { "type": "text", "placeholders": { "senderName": {} } }, - "cuddleContent": "{senderName} se arruncha con usted.", + "cuddleContent": "", "@cuddleContent": { "type": "text", "placeholders": { @@ -3602,156 +3596,88 @@ "senderName": {} } }, - "pleaseEnterRecoveryKey": "Por favor ingrese su clave de recuperación:", + "pleaseEnterRecoveryKey": "", "@pleaseEnterRecoveryKey": {}, - "commandHint_markasdm": "Marcar como chat de mensajes directos", + "commandHint_markasdm": "", "@commandHint_markasdm": {}, "commandHint_markasgroup": "Marcar como grupal", "@commandHint_markasgroup": {}, - "recoveryKey": "Clave de recuperación", + "recoveryKey": "", "@recoveryKey": {}, - "recoveryKeyLost": "¿Clave de recuperación perdida?", + "recoveryKeyLost": "", "@recoveryKeyLost": {}, - "separateChatTypes": "Separar chats privados y grupales", - "@separateChatTypes": { - "type": "text", - "placeholders": {} - }, - "commandHint_create": "Crear un chat grupal vacío\nUse --no-encryption para deshabilitar el cifrado", - "replace": "Reemplazar", - "@replace": {}, - "unsupportedAndroidVersionLong": "", - "@unsupportedAndroidVersionLong": {}, - "storeSecurlyOnThisDevice": "", - "@storeSecurlyOnThisDevice": {}, - "iUnderstand": "", - "@iUnderstand": {}, - "encryptThisChat": "", - "@encryptThisChat": {}, - "letsStart": "", - "@letsStart": {}, - "endToEndEncryption": "", - "@endToEndEncryption": {}, - "openChat": "", - "@openChat": {}, - "screenSharingDetail": "", - "@screenSharingDetail": {}, - "jumpToLastReadMessage": "", - "@jumpToLastReadMessage": {}, - "allRooms": "", - "@allRooms": { - "type": "text", - "placeholders": {} - }, - "widgetVideo": "", - "@widgetVideo": {}, - "dismiss": "", - "@dismiss": {}, - "reportErrorDescription": "", - "@reportErrorDescription": {}, - "unsupportedAndroidVersion": "", - "@unsupportedAndroidVersion": {}, - "noEmailWarning": "", - "@noEmailWarning": {}, - "indexedDbErrorLong": "", - "@indexedDbErrorLong": {}, - "startFirstChat": "", - "@startFirstChat": {}, - "callingAccount": "", - "@callingAccount": {}, - "setColorTheme": "", - "@setColorTheme": {}, - "commandHint_create": "", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "commandHint_dm": "Empezar un chat privado\nUse --no-encryption para deshabilitar el cifrado", - "user": "", - "@user": {}, - "banUserDescription": "", - "@banUserDescription": {}, - "requests": "", - "@requests": {}, - "addToStory": "", - "@addToStory": {}, - "removeDevicesDescription": "", - "@removeDevicesDescription": {}, "separateChatTypes": "", "@separateChatTypes": { "type": "text", "placeholders": {} }, + "commandHint_create": "", + "replace": "Corregir", + "@replace": {}, + "iUnderstand": "Entiendo", + "@iUnderstand": {}, + "@encryptThisChat": {}, + "@letsStart": {}, + "@endToEndEncryption": {}, + "openChat": "Abrir Chat", + "@openChat": {}, + "@jumpToLastReadMessage": {}, + "dismiss": "Descartar", + "@dismiss": {}, + "@reportErrorDescription": {}, + "@startFirstChat": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_dm": "", + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "addToStory": "Agregar a historia", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, "tryAgain": "", "@tryAgain": {}, - "youKickedAndBanned": "", - "@youKickedAndBanned": { - "placeholders": { - "user": {} - } - }, - "showDirectChatsInSpaces": "", - "@showDirectChatsInSpaces": { - "type": "text", - "placeholders": {} - }, + "showDirectChatsInSpaces": "Mostrar chats directos relacionados en Spaces", "unbanUserDescription": "", "@unbanUserDescription": {}, "todoLists": "", "@todoLists": {}, "messagesStyle": "", "@messagesStyle": {}, - "newSpaceDescription": "", "@newSpaceDescription": {}, "chatDescription": "", "@chatDescription": {}, - "callingAccountDetails": "", - "@callingAccountDetails": {}, - "enterSpace": "", + "enterSpace": "Introducir espacio", "@enterSpace": {}, - "reopenChat": "", "@reopenChat": {}, - "pleaseEnterRecoveryKey": "", - "@pleaseEnterRecoveryKey": {}, - "widgetNameError": "", - "@widgetNameError": {}, - "addWidget": "", - "@addWidget": {}, - "noKeyForThisMessage": "", - "@noKeyForThisMessage": {}, "editTodo": "", "@editTodo": {}, - "hydrateTor": "", + "hydrateTor": "TOR Usuarios: Importar exportación de sesión", "@hydrateTor": {}, "pushNotificationsNotAvailable": "", "@pushNotificationsNotAvailable": {}, - "storeInAppleKeyChain": "", - "@storeInAppleKeyChain": {}, - "hydrate": "", + "hydrate": "Restaurar desde archivo de copia de seguridad", "@hydrate": {}, "invalidServerName": "", "@invalidServerName": {}, "chatPermissions": "", "@chatPermissions": {}, - "sender": "", - "@sender": {}, - "storeInAndroidKeystore": "", - "@storeInAndroidKeystore": {}, "signInWithPassword": "", "@signInWithPassword": {}, "pleaseAddATitle": "", "@pleaseAddATitle": {}, "makeAdminDescription": "", "@makeAdminDescription": {}, - "saveKeyManuallyDescription": "", - "@saveKeyManuallyDescription": {}, - "whyIsThisMessageEncrypted": "", - "@whyIsThisMessageEncrypted": {}, "setChatDescription": "", "@setChatDescription": {}, - "dehydrateWarning": "", + "dehydrateWarning": "Esta acción no se puede deshacer. Asegúrese de almacenar de forma segura el archivo de copia de seguridad.", "@dehydrateWarning": {}, - "noOtherDevicesFound": "", "@noOtherDevicesFound": {}, "redactedBy": "", "@redactedBy": { @@ -3760,11 +3686,9 @@ "username": {} } }, - "videoCallsBetaWarning": "", - "@videoCallsBetaWarning": {}, - "storyPrivacyWarning": "", + "storyPrivacyWarning": "Tenga en cuenta que las personas pueden verse y comunicarse entre sí en su historia. Sus historias estarán visibles durante 24 horas, pero no hay garantía de que se eliminen de todos los dispositivos y servidores.", "@storyPrivacyWarning": {}, - "matrixWidgets": "", + "matrixWidgets": "Artilugio de Matrix", "@matrixWidgets": {}, "signInWith": "", "@signInWith": { @@ -3773,39 +3697,17 @@ "provider": {} } }, - "fileIsTooBigForServer": "", "@fileIsTooBigForServer": {}, "noTodosYet": "", "@noTodosYet": {}, - "callingPermissions": "", - "@callingPermissions": {}, - "readUpToHere": "", "@readUpToHere": {}, - "unlockOldMessages": "", - "@unlockOldMessages": {}, - "numChats": "", - "@numChats": { - "type": "number", - "placeholders": { - "number": {} - } - }, "optionalRedactReason": "", "@optionalRedactReason": {}, - "dehydrate": "", + "dehydrate": "Exportar sesión y borrar dispositivo", "@dehydrate": {}, "archiveRoomDescription": "", "@archiveRoomDescription": {}, - "switchToAccount": "", - "@switchToAccount": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "experimentalVideoCalls": "", - "@experimentalVideoCalls": {}, - "pleaseEnterRecoveryKeyDescription": "", + "pleaseEnterRecoveryKeyDescription": "Para desbloquear sus mensajes antiguos, ingrese su clave de recuperación que se generó en una sesión anterior. Su clave de recuperación NO es su contraseña.", "@pleaseEnterRecoveryKeyDescription": {}, "inviteContactToGroupQuestion": "", "@inviteContactToGroupQuestion": {}, @@ -3817,62 +3719,22 @@ "reason": {} } }, - "youHaveWithdrawnTheInvitationFor": "", - "@youHaveWithdrawnTheInvitationFor": { - "placeholders": { - "user": {} - } - }, - "appearOnTopDetails": "", - "@appearOnTopDetails": {}, - "enterRoom": "", - "@enterRoom": {}, - "confirmEventUnpin": "", - "@confirmEventUnpin": {}, - "youInvitedUser": "", - "@youInvitedUser": { - "placeholders": { - "user": {} - } - }, - "fileHasBeenSavedAt": "", - "@fileHasBeenSavedAt": { - "type": "text", - "placeholders": { - "path": {} - } - }, "anyoneCanKnock": "", "@anyoneCanKnock": {}, "redactMessageDescription": "", "@redactMessageDescription": {}, - "recoveryKey": "", - "@recoveryKey": {}, "invalidInput": "", "@invalidInput": {}, "todosUnencrypted": "", "@todosUnencrypted": {}, - "dehydrateTorLong": "", + "dehydrateTorLong": "Para TOR usuarios, se recomienda exportar la sesión antes de cerrar la ventana.", "@dehydrateTorLong": {}, - "doNotShowAgain": "", "@doNotShowAgain": {}, - "report": "", "@report": {}, - "hideUnimportantStateEvents": "", "@hideUnimportantStateEvents": {}, - "screenSharingTitle": "", - "@screenSharingTitle": {}, - "widgetCustom": "", - "@widgetCustom": {}, - "whoCanSeeMyStoriesDesc": "", + "whoCanSeeMyStoriesDesc": "Ten en cuenta que las personas pueden verse y ponerse en contacto en tu historia.", "@whoCanSeeMyStoriesDesc": {}, - "youBannedUser": "", - "@youBannedUser": { - "placeholders": { - "user": {} - } - }, - "unsubscribeStories": "", + "unsubscribeStories": "Darse de baja de historias", "@unsubscribeStories": {}, "hasKnocked": "", "@hasKnocked": { @@ -3880,9 +3742,7 @@ "user": {} } }, - "openLinkInBrowser": "", "@openLinkInBrowser": {}, - "disableEncryptionWarning": "", "@disableEncryptionWarning": {}, "directChat": "", "@directChat": {}, @@ -3897,19 +3757,8 @@ }, "inviteGroupChat": "", "@inviteGroupChat": {}, - "appearOnTop": "", - "@appearOnTop": {}, "invitePrivateChat": "", "@invitePrivateChat": {}, - "foregroundServiceRunning": "", - "@foregroundServiceRunning": {}, - "wasDirectChatDisplayName": "", - "@wasDirectChatDisplayName": { - "type": "text", - "placeholders": { - "oldDisplayName": {} - } - }, "noChatDescriptionYet": "", "@noChatDescriptionYet": {}, "newTodo": "", @@ -3918,29 +3767,20 @@ "@learnMore": {}, "chatDescriptionHasBeenChanged": "", "@chatDescriptionHasBeenChanged": {}, - "dehydrateTor": "", + "dehydrateTor": "TOR Usuarios: Exportar sesión", "@dehydrateTor": {}, "todoListChangedError": "", "@todoListChangedError": {}, - "enterInviteLinkOrMatrixId": "", "@enterInviteLinkOrMatrixId": {}, "roomUpgradeDescription": "", "@roomUpgradeDescription": {}, "pleaseEnterANumber": "", "@pleaseEnterANumber": {}, - "youKicked": "", - "@youKicked": { - "placeholders": { - "user": {} - } - }, "profileNotFound": "", "@profileNotFound": {}, - "jump": "", "@jump": {}, - "sorryThatsNotPossible": "", "@sorryThatsNotPossible": {}, - "storyFrom": "", + "storyFrom": "Historia de {date}: \n{body}", "@storyFrom": { "type": "text", "placeholders": { @@ -3950,11 +3790,6 @@ }, "shareInviteLink": "", "@shareInviteLink": {}, - "commandHint_markasdm": "", - "@commandHint_markasdm": {}, - "recoveryKeyLost": "", - "@recoveryKeyLost": {}, - "deviceKeys": "", "@deviceKeys": {}, "emoteKeyboardNoRecents": "", "@emoteKeyboardNoRecents": { @@ -3963,49 +3798,18 @@ }, "setTheme": "", "@setTheme": {}, - "youJoinedTheChat": "", - "@youJoinedTheChat": {}, - "thisUserHasNotPostedAnythingYet": "", + "thisUserHasNotPostedAnythingYet": "Este usuario aún no ha publicado nada en su historia.", "@thisUserHasNotPostedAnythingYet": {}, - "errorAddingWidget": "", - "@errorAddingWidget": {}, - "commandHint_dm": "", "@commandHint_dm": { "type": "text", "description": "Usage hint for the command /dm" }, - "dehydrate": "Exportar sesión y borrar dispositivo", - "@dehydrate": {}, - "dehydrateWarning": "Esta acción no se puede deshacer. Asegúrese de almacenar de forma segura el archivo de copia de seguridad.", - "@dehydrateWarning": {}, - "dehydrateTor": "TOR Usuarios: Exportar sesión", - "@dehydrateTor": {}, - "dehydrateTorLong": "Para TOR usuarios, se recomienda exportar la sesión antes de cerrar la ventana.", - "@dehydrateTorLong": {}, - "hydrateTor": "TOR Usuarios: Importar exportación de sesión", - "@hydrateTor": {}, - "hydrateTorLong": "¿Exportó su sesión la última vez en TOR? Impórtelo rápidamente y siga chateando.", + "hydrateTorLong": "", "@hydrateTorLong": {}, - "hydrate": "Restaurar desde archivo de copia de seguridad", - "@hydrate": {}, "reportUser": "Reportar usuario", "@reportUser": {}, - "dismiss": "Descartar", - "@dismiss": {}, - "matrixWidgets": "Artilugio de Matrix", - "@matrixWidgets": {}, - "storyPrivacyWarning": "Tenga en cuenta que las personas pueden verse y comunicarse entre sí en su historia. Sus historias estarán visibles durante 24 horas, pero no hay garantía de que se eliminen de todos los dispositivos y servidores.", - "@storyPrivacyWarning": {}, - "iUnderstand": "Entiendo", - "openChat": "Abrir Chat", "markAsRead": "Marcar como leído", - "pleaseEnterRecoveryKeyDescription": "Para desbloquear sus mensajes antiguos, ingrese su clave de recuperación que se generó en una sesión anterior. Su clave de recuperación NO es su contraseña.", - "@pleaseEnterRecoveryKeyDescription": {}, - "addToStory": "Agregar a historia", - "@addToStory": {}, "whoCanSeeMyStories": "¿Quién puede ver mis historias?", - "unsubscribeStories": "Darse de baja de historias", - "thisUserHasNotPostedAnythingYet": "Este usuario aún no ha publicado nada en su historia.", "yourStory": "Su historia", "itToggleDescription": "Esta herramienta de aprendizaje identificará palabras en su idioma base y lo ayudará a traducirlas a su idioma a aprender. Aunque es raro, la AI puede cometer errores de traducción de vez en cuando.", "igcToggleDescription": "Esta herramienta de aprendizaje identificará errores comunes de ortografía, gramática y puntuación en su mensaje y sugerirá correcciones. Aunque es raro, la AI puede cometer errores de corrección de vez en cuando.", @@ -4023,11 +3827,8 @@ "kickAllStudentsConfirmation": "¿Estás seguro de que quieres echar a todos los estudiantes?", "inviteAllStudents": "Invitar a todos los estudiantes", "inviteAllStudentsConfirmation": "¿Estás seguro de que quieres invitar a todos los estudiantes?", - "whoCanSeeMyStoriesDesc": "Ten en cuenta que las personas pueden verse y ponerse en contacto en tu historia.", "taAndGaTooltip": "Uso de la L2 con ayuda de traducción y asistencia gramatical.", - "storyFrom": "Historia de {date}: \n{body}", "createNewSpace": "Crear una sala de intercambio", - "enterASpacepName": "Introduzca un nombre", "oneToOneChatsWithinClass": "Chats privados dentro de la sala", "oneToOneChatsWithinClassDesc": "Si permite chats privados, los alumnos pueden iniciar y utilizar chats privados con otros participantes de la sala. De lo contrario, sólo podrán participar en chats de grupo.", "subscriptionManagementUnavailable": "Gestión de suscripciones no disponible", @@ -4483,12 +4284,10 @@ "allPrivateChats": "Todos los chats privados (incluso con bots) en clase", "chatHasBeenAddedToThisSpace": "Se ha añadido el chat a este espacio", "classes": "Clases", - "showDirectChatsInSpaces": "Mostrar chats directos relacionados en Spaces", "spaceIsPublic": "El espacio es público", "removeFromSpace": "Retirar del espacio", "addToSpaceDescription": "Seleccione un espacio para añadirle este chat.", "newSpace": "Nueva clase", - "enterSpace": "Introducir espacio", "allSpaces": "Todos los espacios", "deleteSpace": "Borrar espacio", "areYouSureDeleteClass": "¿Seguro que quieres borrar este espacio?", @@ -4604,60 +4403,81 @@ "suggestExchangeDesc": "Los intercambios sugeridos aparecerán en la lista de chat de {spaceName}.", "acceptSelection": "Aceptar corrección", "acceptSelectionAnyway": "Use esto de todos modos", - "replace": "Corregir", "makingActivity": "Actividad de fabricación", "why": "¿Por qué?", "definition": "Definición", "exampleSentence": "Ejemplo de frase", "addToClassTitle": "Añadir intercambio a la clase", - "youUnbannedUser": "", - "@youUnbannedUser": { - "placeholders": { - "user": {} - } - }, - "emojis": "", - "@emojis": {}, "pleaseTryAgainLaterOrChooseDifferentServer": "", "@pleaseTryAgainLaterOrChooseDifferentServer": {}, "createGroup": "", "@createGroup": {}, - "hydrateTorLong": "", - "@hydrateTorLong": {}, - "custom": "", - "@custom": {}, - "noBackupWarning": "", "@noBackupWarning": {}, - "editWidgets": "", - "@editWidgets": {}, - "storeInSecureStorageDescription": "", - "@storeInSecureStorageDescription": {}, "kickUserDescription": "", "@kickUserDescription": {}, - "pinMessage": "", - "@pinMessage": {}, "invite": "", "@invite": {}, "continueWith": "", "@continueWith": {}, - "indexedDbErrorTitle": "", - "@indexedDbErrorTitle": {}, - "googlyEyesContent": "", - "@googlyEyesContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "cuddleContent": "", - "@cuddleContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "commandHint_googly": "", "@commandHint_googly": {}, - "placeCall": "", - "@placeCall": {} + "notAnImage": "No es un archivo de imagen.", + "importNow": "Importar ahora", + "importEmojis": "Importar emojis", + "importFromZipFile": "Importar desde archivo .zip", + "importZipFile": "Importar archivo .zip", + "exportEmotePack": "Exportar Emote pack como .zip", + "savedEmotePack": "¡Paquete de emoticonos guardado en {path}!", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "sendTypingNotifications": "Enviar notificaciones de mecanografía", + "reportToTeacher": "¿A quién desea informar de este mensaje?", + "reportMessageTitle": "{reportingUserId} ha informado de un mensaje de {reportedUserId} en el chat {roomName}.", + "@reportMessageTitle": { + "placeholders": { + "reportingUserId": {}, + "reportedUserId": {}, + "roomName": {} + } + }, + "reportMessageBody": "Mensaje: {reportedMessage}\nMotivo: {reason}", + "@reportMessageBody": { + "placeholders": { + "reportedMessage": {}, + "reason": {} + } + }, + "noTeachersFound": "No se han encontrado profesores a los que informar", + "noAddToSpacePermissions": "No puedes añadir un chat a este espacio", + "alreadyInSpace": "El chat ya está en este espacio", + "yourGlobalUserIdIs": "Tu ID de usuario global es:", + "noUsersFoundWithQuery": "Lamentablemente no se ha encontrado ningún usuario con \"{query}\". Por favor, compruebe si ha cometido un error tipográfico.", + "@noUsersFoundWithQuery": { + "type": "text", + "placeholders": { + "query": {} + } + }, + "searchChatsRooms": "Busca #chats, @users...", + "groupName": "Nombre del grupo", + "createGroupAndInviteUsers": "Crear un grupo e invitar a los usuarios", + "groupCanBeFoundViaSearch": "El grupo se puede encontrar a través de la búsqueda", + "inNoSpaces": "No es miembro de ninguna clase o bolsa", + "createClass": "Crear clase", + "createExchange": "Crear intercambio", + "viewArchive": "Ver archivo", + "trialExpiration": "Su prueba gratuita caduca el {expiration}.", + "@trialExpiration": { + "placeholders": { + "expiration": {} + } + }, + "freeTrialDesc": "Los nuevos usuarios reciben una semana de prueba gratuita de Pangea Chat", + "activateTrial": "Activar prueba", + "successfullySubscribed": "Se ha suscrito correctamente.", + "clickToManageSubscription": "Haga clic aquí para gestionar su suscripción.", + "emptyInviteWarning": "Añade este chat a una clase o intercambio para invitar a otros usuarios." }