Merge branch 'main' into save-selection

pull/1183/head
ggurdin 1 year ago committed by GitHub
commit 3b645b023e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -3128,7 +3128,7 @@
"maybeLater": "Maybe Later", "maybeLater": "Maybe Later",
"mainMenu": "Main Menu", "mainMenu": "Main Menu",
"toggleImmersionMode": "Immersion Mode", "toggleImmersionMode": "Immersion Mode",
"toggleImmersionModeDesc": "When enabled, all messages are displayed in your target language and you can click the message to access definitions and translations.", "toggleImmersionModeDesc": "When enabled, all messages are displayed in your target language. This setting is most useful in language exchanges.",
"itToggleDescription": "This language learning tool will identify words in your base language and help you translate them to your target language. Though rare, the AI can make translation errors.", "itToggleDescription": "This language learning tool will identify words in your base language and help you translate them to your target language. Though rare, the AI can make translation errors.",
"igcToggleDescription": "This language learning tool will identify common spelling, grammar and punctuation errors in your message and suggest corrections. Though rare, the AI can make correction errors.", "igcToggleDescription": "This language learning tool will identify common spelling, grammar and punctuation errors in your message and suggest corrections. Though rare, the AI can make correction errors.",
"sendOnEnterDescription": "Turn this off to be able to add line spaces in messages. When the toggle is off on the browser app, you can press Shift + Enter to start a new line. When the toggle is off on mobile apps, just Enter will start a new line.", "sendOnEnterDescription": "Turn this off to be able to add line spaces in messages. When the toggle is off on the browser app, you can press Shift + Enter to start a new line. When the toggle is off on mobile apps, just Enter will start a new line.",
@ -3948,8 +3948,16 @@
"roomDataMissing": "Some data may be missing from rooms in which you are not a member.", "roomDataMissing": "Some data may be missing from rooms in which you are not a member.",
"updatePhoneOS": "You may need to update your device's OS version.", "updatePhoneOS": "You may need to update your device's OS version.",
"wordsPerMinute": "Words per minute", "wordsPerMinute": "Words per minute",
"autoIGCToolName": "Run Language Assistance Automatically",
"autoIGCToolDescription": "Automatically run language assistance after typing messages",
"runGrammarCorrection": "Run grammar correction",
"grammarCorrectionFailed": "Grammar correction failed",
"grammarCorrectionComplete": "Grammar correction complete",
"leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", "leaveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.",
"archiveSpaceDescription": "All chats within this space will be moved to the archive for yourself and other non-admin users.", "archiveSpaceDescription": "All chats within this space will be moved to the archive for yourself and other non-admin users.",
"leaveSpaceDescription": "All chats within this space will be moved to the archive. Other users will be able to see that you have left the space.", "leaveSpaceDescription": "All chats within this space will be moved to the archive. Other users will be able to see that you have left the space.",
"onlyAdminDescription": "Since there are no other admins, all other participants will also be removed." "onlyAdminDescription": "Since there are no other admins, all other participants will also be removed.",
"tooltipInstructionsTitle": "Not sure what that does?",
"tooltipInstructionsMobileBody": "Press and hold items to view tooltips.",
"tooltipInstructionsBrowserBody": "Hover over items to view tooltips."
} }

@ -3281,7 +3281,7 @@
"generateVocabulary": "Generar vocabulario basado en el título y la descripción", "generateVocabulary": "Generar vocabulario basado en el título y la descripción",
"generatePrompts": "Generar preguntas basado en el título y la descripción", "generatePrompts": "Generar preguntas basado en el título y la descripción",
"toggleImmersionMode": "Modo de inmersión", "toggleImmersionMode": "Modo de inmersión",
"toggleImmersionModeDesc": "Cuando está habilitado, todos los mensajes se muestran en su idioma de destino y puede hacer clic en el mensaje para acceder a definiciones y traducciones.", "toggleImmersionModeDesc": "Cuando está habilitado, todos los mensajes se muestran en su idioma de destino. Esta configuración es más útil en intercambios de idiomas.",
"subscribe": "Subscríbase", "subscribe": "Subscríbase",
"getAccess": "Activar herramientas", "getAccess": "Activar herramientas",
"subscriptionDesc": "¡Enviar y recibir mensajes es gratis! Suscríbase para aceder a la traducción interactiva, la revisión gramatical y el análisis de aprendizaje.", "subscriptionDesc": "¡Enviar y recibir mensajes es gratis! Suscríbase para aceder a la traducción interactiva, la revisión gramatical y el análisis de aprendizaje.",

@ -1327,9 +1327,18 @@ class ChatController extends State<ChatPageWithRoom>
} }
// Pangea# // Pangea#
if (!event.redacted) { if (!event.redacted) {
if (selectedEvents.contains(event)) { // #Pangea
// If previous selectedEvent has same eventId, delete previous selectedEvent
final matches =
selectedEvents.where((e) => e.eventId == event.eventId).toList();
if (matches.isNotEmpty) {
// if (selectedEvents.contains(event)) {
// Pangea#
setState( setState(
() => selectedEvents.remove(event), // #Pangea
() => selectedEvents.remove(matches.first),
// () => selectedEvents.remove(event),
// Pangea#
); );
} else { } else {
setState( setState(

@ -9,6 +9,7 @@ import 'package:fluffychat/pages/chat/reactions_picker.dart';
import 'package:fluffychat/pages/chat/reply_display.dart'; import 'package:fluffychat/pages/chat/reply_display.dart';
import 'package:fluffychat/pangea/choreographer/widgets/has_error_button.dart'; import 'package:fluffychat/pangea/choreographer/widgets/has_error_button.dart';
import 'package:fluffychat/pangea/choreographer/widgets/language_permissions_warning_buttons.dart'; import 'package:fluffychat/pangea/choreographer/widgets/language_permissions_warning_buttons.dart';
import 'package:fluffychat/pangea/choreographer/widgets/start_igc_button.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/pages/class_analytics/measure_able.dart'; import 'package:fluffychat/pangea/pages/class_analytics/measure_able.dart';
import 'package:fluffychat/utils/account_config.dart'; import 'package:fluffychat/utils/account_config.dart';
@ -449,8 +450,8 @@ class ChatView extends StatelessWidget {
// #Pangea // #Pangea
// if (controller.dragging) // if (controller.dragging)
// Container( // Container(
// color: Theme.of(context) // color: Theme.of(context)
// .scaffoldBackgroundColor // .scaffoldBackgroundColor
// .withOpacity(0.9), // .withOpacity(0.9),
// alignment: Alignment.center, // alignment: Alignment.center,
// child: const Icon( // child: const Icon(
@ -458,6 +459,11 @@ class ChatView extends StatelessWidget {
// size: 100, // size: 100,
// ), // ),
// ), // ),
Positioned(
left: 20,
bottom: 75,
child: StartIGCButton(controller: controller),
),
// Pangea# // Pangea#
], ],
), ),

@ -199,18 +199,8 @@ class MessageContent extends StatelessWidget {
case MessageTypes.Notice: case MessageTypes.Notice:
case MessageTypes.Emote: case MessageTypes.Emote:
if (AppConfig.renderHtml && if (AppConfig.renderHtml &&
!event.redacted && !event.redacted &&
event.isRichMessage event.isRichMessage) {
// #Pangea
&&
!(pangeaMessageEvent?.showRichText(
selected,
isOverlay: isOverlay,
highlighted: toolbarController?.highlighted ?? false,
) ??
false)
// Pangea#
) {
var html = event.formattedText; var html = event.formattedText;
if (event.messageType == MessageTypes.Emote) { if (event.messageType == MessageTypes.Emote) {
html = '* $html'; html = '* $html';
@ -306,18 +296,17 @@ class MessageContent extends StatelessWidget {
decoration: event.redacted ? TextDecoration.lineThrough : null, decoration: event.redacted ? TextDecoration.lineThrough : null,
height: 1.3, height: 1.3,
); );
if (pangeaMessageEvent?.showRichText( if (immersionMode && pangeaMessageEvent != null) {
selected,
isOverlay: isOverlay,
highlighted: toolbarController?.highlighted ?? false,
) ??
false) {
return PangeaRichText( return PangeaRichText(
style: messageTextStyle, style: messageTextStyle,
pangeaMessageEvent: pangeaMessageEvent!, pangeaMessageEvent: pangeaMessageEvent!,
immersionMode: immersionMode, immersionMode: immersionMode,
toolbarController: toolbarController, toolbarController: toolbarController,
); );
} else if (pangeaMessageEvent != null) {
toolbarController?.toolbar?.textSelection.setMessageText(
pangeaMessageEvent!.body,
);
} }
// Pangea# // Pangea#
return FutureBuilder<String>( return FutureBuilder<String>(

@ -105,6 +105,12 @@ class ChatListController extends State<ChatList>
selectedRoomIds.clear(); selectedRoomIds.clear();
activeSpaceId = spaceId; activeSpaceId = spaceId;
activeFilter = ActiveFilter.spaces; activeFilter = ActiveFilter.spaces;
// #Pangea
// don't show all spaces view if in column mode
if (spaceId == null && FluffyThemes.isColumnMode(context)) {
activeFilter = ActiveFilter.allChats;
}
// Pangea#
}); });
} }
@ -693,7 +699,7 @@ class ChatListController extends State<ChatList>
title: L10n.of(context)!.areYouSure, title: L10n.of(context)!.areYouSure,
okLabel: L10n.of(context)!.yes, okLabel: L10n.of(context)!.yes,
cancelLabel: L10n.of(context)!.cancel, cancelLabel: L10n.of(context)!.cancel,
message: onlyAdmin message: onlyAdmin && selectedRoomIds.length == 1
? L10n.of(context)!.onlyAdminDescription ? L10n.of(context)!.onlyAdminDescription
: L10n.of(context)!.leaveRoomDescription, : L10n.of(context)!.leaveRoomDescription,
) == ) ==

@ -171,6 +171,12 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
onPressed: controller.toggleMuted, onPressed: controller.toggleMuted,
), ),
// #Pangea // #Pangea
if (controller.selectedRoomIds.length > 1)
IconButton(
icon: const Icon(Icons.arrow_forward),
tooltip: L10n.of(context)!.leave,
onPressed: controller.leaveAction,
),
if (controller.selectedRoomIds.length == 1 && if (controller.selectedRoomIds.length == 1 &&
!(Matrix.of(context) !(Matrix.of(context)
.client .client

@ -147,7 +147,10 @@ class _SpaceViewState extends State<SpaceView> {
if (activeSpace != null) { if (activeSpace != null) {
await setChatCount( await setChatCount(
activeSpace, activeSpace,
_lastResponse[activeSpaceId], _lastResponse[activeSpaceId] ??
GetSpaceHierarchyResponse(
rooms: [],
),
); );
} }
// Pangea# // Pangea#

@ -1,18 +1,17 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:fluffychat/pangea/utils/logout.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:fluffychat/pangea/utils/logout.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import '../../widgets/matrix.dart'; import '../../widgets/matrix.dart';
import 'settings_view.dart'; import 'settings_view.dart';
@ -171,6 +170,10 @@ class SettingsController extends State<Settings> {
// Pangea# // Pangea#
super.initState(); super.initState();
// #Pangea
profileUpdated = true;
profileFuture = null;
// Pangea#
} }
void checkBootstrap() async { void checkBootstrap() async {

@ -13,6 +13,7 @@ import 'package:fluffychat/pangea/enum/edit_type.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
import 'package:fluffychat/pangea/models/class_model.dart'; import 'package:fluffychat/pangea/models/class_model.dart';
import 'package:fluffychat/pangea/models/it_step.dart'; import 'package:fluffychat/pangea/models/it_step.dart';
import 'package:fluffychat/pangea/models/language_detection_model.dart';
import 'package:fluffychat/pangea/models/representation_content_model.dart'; import 'package:fluffychat/pangea/models/representation_content_model.dart';
import 'package:fluffychat/pangea/models/tokens_event_content_model.dart'; import 'package:fluffychat/pangea/models/tokens_event_content_model.dart';
import 'package:fluffychat/pangea/utils/any_state_holder.dart'; import 'package:fluffychat/pangea/utils/any_state_holder.dart';
@ -51,7 +52,7 @@ class Choreographer {
// last checked by IGC or translation // last checked by IGC or translation
String? _lastChecked; String? _lastChecked;
ChoreoMode choreoMode = ChoreoMode.igc; ChoreoMode choreoMode = ChoreoMode.igc;
final StreamController stateListener = StreamController(); final StreamController stateListener = StreamController.broadcast();
StreamSubscription? trialStream; StreamSubscription? trialStream;
Choreographer(this.pangeaController, this.chatController) { Choreographer(this.pangeaController, this.chatController) {
@ -93,7 +94,7 @@ class Choreographer {
} }
} }
void _sendWithIGC(BuildContext context) { Future<void> _sendWithIGC(BuildContext context) async {
if (igc.canSendMessage) { if (igc.canSendMessage) {
final PangeaRepresentation? originalWritten = final PangeaRepresentation? originalWritten =
choreoRecord.includedIT && itController.sourceText != null choreoRecord.includedIT && itController.sourceText != null
@ -105,7 +106,6 @@ class Choreographer {
) )
: null; : null;
// PTODO - just put this in original message event
final PangeaRepresentation originalSent = PangeaRepresentation( final PangeaRepresentation originalSent = PangeaRepresentation(
langCode: langCodeOfCurrentText ?? LanguageKeys.unknownLanguage, langCode: langCodeOfCurrentText ?? LanguageKeys.unknownLanguage,
text: currentText, text: currentText,
@ -115,6 +115,22 @@ class Choreographer {
final ChoreoRecord? applicableChoreo = final ChoreoRecord? applicableChoreo =
isITandIGCEnabled && igc.igcTextData != null ? choreoRecord : null; isITandIGCEnabled && igc.igcTextData != null ? choreoRecord : null;
// if the message has not been processed to determine its language
// then run it through the language detection endpoint. If the detection
// confidence is high enough, use that language code as the message's language
// to save that pangea representation
if (applicableChoreo == null) {
final resp = await pangeaController.languageDetection.detectLanguage(
currentText,
pangeaController.languageController.userL2?.langCode,
pangeaController.languageController.userL1?.langCode,
);
final LanguageDetection? bestDetection = resp.bestDetection();
if (bestDetection != null) {
originalSent.langCode = bestDetection.langCode;
}
}
final UseType useType = useTypeCalculator(applicableChoreo); final UseType useType = useTypeCalculator(applicableChoreo);
debugPrint("use type in choreographer $useType"); debugPrint("use type in choreographer $useType");
@ -205,14 +221,18 @@ class Choreographer {
textController.editType = EditType.keyboard; textController.editType = EditType.keyboard;
} }
Future<void> getLanguageHelp([bool tokensOnly = false]) async { Future<void> getLanguageHelp([
bool tokensOnly = false,
bool manual = false,
]) async {
try { try {
if (errorService.isError) return; if (errorService.isError) return;
final CanSendStatus canSendStatus = final CanSendStatus canSendStatus =
pangeaController.subscriptionController.canSendStatus; pangeaController.subscriptionController.canSendStatus;
if (canSendStatus != CanSendStatus.subscribed || if (canSendStatus != CanSendStatus.subscribed ||
(!igcEnabled && !itEnabled)) { (!igcEnabled && !itEnabled) ||
(!isAutoIGCEnabled && !manual && choreoMode != ChoreoMode.it)) {
return; return;
} }
@ -525,14 +545,50 @@ class Choreographer {
chatController.room, chatController.room,
); );
bool get translationEnabled => // bool get translationEnabled =>
pangeaController.permissionsController.isToolEnabled( // pangeaController.permissionsController.isToolEnabled(
ToolSetting.translations, // ToolSetting.translations,
chatController.room, // chatController.room,
); // );
bool get isITandIGCEnabled => bool get isITandIGCEnabled =>
pangeaController.permissionsController.isWritingAssistanceEnabled( pangeaController.permissionsController.isWritingAssistanceEnabled(
chatController.room, chatController.room,
); );
bool get isAutoIGCEnabled =>
pangeaController.permissionsController.isToolEnabled(
ToolSetting.autoIGC,
chatController.room,
);
AssistanceState get assistanceState {
if (currentText.isEmpty && itController.sourceText == null) {
return AssistanceState.noMessage;
}
if (igc.igcTextData?.matches.isNotEmpty ?? false) {
return AssistanceState.fetched;
}
if (isFetching) {
return AssistanceState.fetching;
}
if (igc.igcTextData == null) {
return AssistanceState.notFetched;
}
return AssistanceState.complete;
}
}
// assistance state is, user has not typed a message, user has typed a message and IGC has not run,
// IGC is running, IGC has run and there are remaining steps (either IT or IGC), or all steps are done
enum AssistanceState {
noMessage,
notFetched,
fetching,
fetched,
complete,
} }

@ -183,7 +183,7 @@ class ITController {
} }
} }
Future<void>getNextTranslationData() async { Future<void> getNextTranslationData() async {
try { try {
if (completedITSteps.length < goldRouteTracker.continuances.length) { if (completedITSteps.length < goldRouteTracker.continuances.length) {
final String currentText = choreographer.currentText; final String currentText = choreographer.currentText;
@ -478,5 +478,5 @@ class CurrentITStep {
// get continuance with highest level // get continuance with highest level
Continuance get best => Continuance get best =>
continuances.reduce((a, b) => a.level > b.level ? a : b); continuances.reduce((a, b) => a.level < b.level ? a : b);
} }

@ -17,9 +17,9 @@ class LanguageDisplayToggle extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (!controller.choreographer.translationEnabled) { // if (!controller.choreographer.translationEnabled) {
return const SizedBox(); // return const SizedBox();
} // }
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,

@ -1,8 +1,7 @@
import 'package:fluffychat/pangea/constants/colors.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/pangea/constants/colors.dart';
import '../../../pages/chat/chat.dart'; import '../../../pages/chat/chat.dart';
class ChoreographerSendButton extends StatelessWidget { class ChoreographerSendButton extends StatelessWidget {
@ -16,7 +15,8 @@ class ChoreographerSendButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// commit for cicd // commit for cicd
return controller.choreographer.isFetching return controller.choreographer.isFetching &&
controller.choreographer.isAutoIGCEnabled
? Container( ? Container(
height: 56, height: 56,
width: 56, width: 56,
@ -28,7 +28,8 @@ class ChoreographerSendButton extends StatelessWidget {
alignment: Alignment.center, alignment: Alignment.center,
child: IconButton( child: IconButton(
icon: const Icon(Icons.send_outlined), icon: const Icon(Icons.send_outlined),
color: controller.choreographer.igc.canSendMessage color: controller.choreographer.igc.canSendMessage ||
!controller.choreographer.isAutoIGCEnabled
? null ? null
: PangeaColors.igcError, : PangeaColors.igcError,
onPressed: () { onPressed: () {

@ -0,0 +1,150 @@
import 'dart:async';
import 'dart:math' as math;
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart';
import 'package:fluffychat/pangea/constants/colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import '../../../pages/chat/chat.dart';
class StartIGCButton extends StatefulWidget {
const StartIGCButton({
super.key,
required this.controller,
});
final ChatController controller;
@override
State<StartIGCButton> createState() => StartIGCButtonState();
}
class StartIGCButtonState extends State<StartIGCButton>
with SingleTickerProviderStateMixin {
AssistanceState get assistanceState =>
widget.controller.choreographer.assistanceState;
AnimationController? _controller;
StreamSubscription? choreoListener;
AssistanceState? prevState;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
choreoListener = widget.controller.choreographer.stateListener.stream
.listen(updateSpinnerState);
super.initState();
}
void updateSpinnerState(_) {
if (prevState != AssistanceState.fetching &&
assistanceState == AssistanceState.fetching) {
_controller?.repeat();
} else if (prevState == AssistanceState.fetching &&
assistanceState != AssistanceState.fetching) {
_controller?.stop();
_controller?.reverse();
}
setState(() => prevState = assistanceState);
}
@override
Widget build(BuildContext context) {
if (widget.controller.choreographer.isAutoIGCEnabled) {
return const SizedBox.shrink();
}
final Widget icon = Icon(
Icons.autorenew_rounded,
size: 46,
color: assistanceState.stateColor,
);
return SizedBox(
height: 50,
width: 50,
child: FloatingActionButton(
tooltip: assistanceState.tooltip(
L10n.of(context)!,
),
backgroundColor: Colors.white,
disabledElevation: 0,
shape: const CircleBorder(),
onPressed: () {
if (assistanceState != AssistanceState.complete) {
widget.controller.choreographer.getLanguageHelp(
false,
true,
);
}
},
child: Stack(
alignment: Alignment.center,
children: [
_controller != null
? RotationTransition(
turns: Tween(begin: 0.0, end: math.pi * 2)
.animate(_controller!),
child: icon,
)
: icon,
Container(
width: 26,
height: 26,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
),
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: assistanceState.stateColor,
),
),
const Icon(
size: 16,
Icons.check,
color: Colors.white,
),
],
),
),
);
}
}
extension AssistanceStateExtension on AssistanceState {
Color get stateColor {
switch (this) {
case AssistanceState.noMessage:
case AssistanceState.notFetched:
case AssistanceState.fetching:
return AppConfig.primaryColor;
case AssistanceState.fetched:
return PangeaColors.igcError;
case AssistanceState.complete:
return AppConfig.success;
}
}
String tooltip(L10n l10n) {
switch (this) {
case AssistanceState.noMessage:
case AssistanceState.notFetched:
return l10n.runGrammarCorrection;
case AssistanceState.fetching:
return "";
case AssistanceState.fetched:
return l10n.grammarCorrectionFailed;
case AssistanceState.complete:
return l10n.grammarCorrectionComplete;
}
}
}

@ -54,6 +54,7 @@ class ModelKey {
static const String offset = "offset"; static const String offset = "offset";
static const String length = "length"; static const String length = "length";
static const String langCode = 'lang_code'; static const String langCode = 'lang_code';
static const String confidence = 'confidence';
// some old analytics rooms have langCode instead of lang_code in the room creation content // some old analytics rooms have langCode instead of lang_code in the room creation content
static const String oldLangCode = 'langCode'; static const String oldLangCode = 'langCode';
static const String wordLang = "word_lang"; static const String wordLang = "word_lang";

@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:fluffychat/pangea/config/environment.dart'; import 'package:fluffychat/pangea/config/environment.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/models/language_detection_model.dart';
import 'package:fluffychat/pangea/network/urls.dart'; import 'package:fluffychat/pangea/network/urls.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -48,7 +49,7 @@ class LanguageDetectionRequest {
} }
class LanguageDetectionResponse { class LanguageDetectionResponse {
List<Map<String, dynamic>> detections; List<LanguageDetection> detections;
String fullText; String fullText;
LanguageDetectionResponse({ LanguageDetectionResponse({
@ -58,7 +59,11 @@ class LanguageDetectionResponse {
factory LanguageDetectionResponse.fromJson(Map<String, dynamic> json) { factory LanguageDetectionResponse.fromJson(Map<String, dynamic> json) {
return LanguageDetectionResponse( return LanguageDetectionResponse(
detections: List<Map<String, dynamic>>.from(json['detections']), detections: List<LanguageDetection>.from(
json['detections'].map(
(e) => LanguageDetection.fromJson(e),
),
),
fullText: json['full_text'], fullText: json['full_text'],
); );
} }
@ -69,6 +74,20 @@ class LanguageDetectionResponse {
'full_text': fullText, 'full_text': fullText,
}; };
} }
LanguageDetection? get _bestDetection {
detections.sort((a, b) => b.confidence.compareTo(a.confidence));
return detections.isNotEmpty ? detections.first : null;
}
final double _confidenceThreshold = 0.95;
LanguageDetection? bestDetection({double? threshold}) {
threshold ??= _confidenceThreshold;
return (_bestDetection?.confidence ?? 0) >= _confidenceThreshold
? _bestDetection!
: null;
}
} }
class _LanguageDetectionCacheItem { class _LanguageDetectionCacheItem {
@ -103,6 +122,19 @@ class LanguageDetectionController {
_cacheClearTimer?.cancel(); _cacheClearTimer?.cancel();
} }
Future<LanguageDetectionResponse> detectLanguage(
String fullText,
String? userL2,
String? userL1,
) async {
final LanguageDetectionRequest params = LanguageDetectionRequest(
fullText: fullText,
userL1: userL1,
userL2: userL2,
);
return get(params);
}
Future<LanguageDetectionResponse> get( Future<LanguageDetectionResponse> get(
LanguageDetectionRequest params, LanguageDetectionRequest params,
) async { ) async {

@ -8,8 +8,14 @@ class LocalSettings {
_pangeaController = pangeaController; _pangeaController = pangeaController;
} }
bool userLanguageToolSetting(ToolSetting setting) => bool userLanguageToolSetting(ToolSetting setting) {
_pangeaController.pStoreService.read(setting.toString()) ?? true; final profileSetting =
_pangeaController.pStoreService.read(setting.toString());
if (profileSetting != null) {
return profileSetting;
}
return setting == ToolSetting.immersionMode ? false : true;
}
// bool get userEnableIT => // bool get userEnableIT =>
// _pangeaController.pStoreService.read(ToolSetting.interactiveTranslator.toString()) ?? true; // _pangeaController.pStoreService.read(ToolSetting.interactiveTranslator.toString()) ?? true;

@ -131,7 +131,7 @@ class UserController extends BaseController {
final bool? immersionMode = final bool? immersionMode =
migratedProfileInfo(MatrixProfile.immersionMode); migratedProfileInfo(MatrixProfile.immersionMode);
final bool? definitions = migratedProfileInfo(MatrixProfile.definitions); final bool? definitions = migratedProfileInfo(MatrixProfile.definitions);
final bool? translations = migratedProfileInfo(MatrixProfile.translations); // final bool? translations = migratedProfileInfo(MatrixProfile.translations);
final bool? showItInstructions = final bool? showItInstructions =
migratedProfileInfo(MatrixProfile.showedItInstructions); migratedProfileInfo(MatrixProfile.showedItInstructions);
final bool? showClickMessage = final bool? showClickMessage =
@ -147,7 +147,7 @@ class UserController extends BaseController {
interactiveGrammar: interactiveGrammar, interactiveGrammar: interactiveGrammar,
immersionMode: immersionMode, immersionMode: immersionMode,
definitions: definitions, definitions: definitions,
translations: translations, // translations: translations,
showedItInstructions: showItInstructions, showedItInstructions: showItInstructions,
showedClickMessage: showClickMessage, showedClickMessage: showClickMessage,
showedBlurMeansTranslate: showBlurMeansTranslate, showedBlurMeansTranslate: showBlurMeansTranslate,
@ -228,10 +228,11 @@ class UserController extends BaseController {
bool? interactiveGrammar, bool? interactiveGrammar,
bool? immersionMode, bool? immersionMode,
bool? definitions, bool? definitions,
bool? translations, // bool? translations,
bool? showedItInstructions, bool? showedItInstructions,
bool? showedClickMessage, bool? showedClickMessage,
bool? showedBlurMeansTranslate, bool? showedBlurMeansTranslate,
bool? showedTooltipInstructions,
String? createdAt, String? createdAt,
String? targetLanguage, String? targetLanguage,
String? sourceLanguage, String? sourceLanguage,
@ -280,12 +281,12 @@ class UserController extends BaseController {
definitions, definitions,
); );
} }
if (translations != null) { // if (translations != null) {
await _pangeaController.pStoreService.save( // await _pangeaController.pStoreService.save(
MatrixProfile.translations.title, // MatrixProfile.translations.title,
translations, // translations,
); // );
} // }
if (showedItInstructions != null) { if (showedItInstructions != null) {
await _pangeaController.pStoreService.save( await _pangeaController.pStoreService.save(
MatrixProfile.showedItInstructions.title, MatrixProfile.showedItInstructions.title,
@ -304,6 +305,12 @@ class UserController extends BaseController {
showedBlurMeansTranslate, showedBlurMeansTranslate,
); );
} }
if (showedTooltipInstructions != null) {
await _pangeaController.pStoreService.save(
MatrixProfile.showedTooltipInstructions.title,
showedTooltipInstructions,
);
}
if (createdAt != null) { if (createdAt != null) {
await _pangeaController.pStoreService.save( await _pangeaController.pStoreService.save(
MatrixProfile.createdAt.title, MatrixProfile.createdAt.title,

@ -80,29 +80,6 @@ class PangeaMessageEvent {
return _latestEdit; return _latestEdit;
} }
bool showRichText(
bool selected, {
bool highlighted = false,
bool isOverlay = false,
}) {
if (!_isValidPangeaMessageEvent) {
return false;
}
if ([EventStatus.error, EventStatus.sending].contains(_event.status)) {
return false;
}
if (isOverlay) return true;
// if ownMessage, don't show rich text if not selected or highlighted
// and don't show is the message is not an overlay
if (ownMessage && ((!selected && !highlighted) || !isOverlay)) {
return false;
}
return true;
}
Future<PangeaAudioFile> getMatrixAudioFile( Future<PangeaAudioFile> getMatrixAudioFile(
String langCode, String langCode,
BuildContext context, BuildContext context,

@ -1,13 +1,12 @@
import 'dart:developer'; import 'dart:developer';
import 'package:fluffychat/pangea/constants/model_keys.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:fluffychat/pangea/constants/model_keys.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import '../constants/class_default_values.dart'; import '../constants/class_default_values.dart';
import '../constants/language_keys.dart'; import '../constants/language_keys.dart';
import '../constants/pangea_event_types.dart'; import '../constants/pangea_event_types.dart';
@ -124,6 +123,7 @@ class PangeaRoomRules {
int immersionMode; int immersionMode;
int definitions; int definitions;
int translations; int translations;
int autoIGC;
PangeaRoomRules({ PangeaRoomRules({
this.isPublic = false, this.isPublic = false,
@ -142,6 +142,7 @@ class PangeaRoomRules {
this.immersionMode = ClassDefaultValues.languageToolPermissions, this.immersionMode = ClassDefaultValues.languageToolPermissions,
this.definitions = ClassDefaultValues.languageToolPermissions, this.definitions = ClassDefaultValues.languageToolPermissions,
this.translations = ClassDefaultValues.languageToolPermissions, this.translations = ClassDefaultValues.languageToolPermissions,
this.autoIGC = ClassDefaultValues.languageToolPermissions,
}); });
updatePermission(String key, bool value) { updatePermission(String key, bool value) {
@ -198,8 +199,11 @@ class PangeaRoomRules {
case ToolSetting.definitions: case ToolSetting.definitions:
definitions = value; definitions = value;
break; break;
case ToolSetting.translations: // case ToolSetting.translations:
translations = value; // translations = value;
// break;
case ToolSetting.autoIGC:
autoIGC = value;
break; break;
default: default:
throw Exception('Invalid key for setting permissions - $setting'); throw Exception('Invalid key for setting permissions - $setting');
@ -235,6 +239,7 @@ class PangeaRoomRules {
json['definitions'] ?? ClassDefaultValues.languageToolPermissions, json['definitions'] ?? ClassDefaultValues.languageToolPermissions,
translations: translations:
json['translations'] ?? ClassDefaultValues.languageToolPermissions, json['translations'] ?? ClassDefaultValues.languageToolPermissions,
autoIGC: json['auto_igc'] ?? ClassDefaultValues.languageToolPermissions,
); );
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -256,6 +261,7 @@ class PangeaRoomRules {
data['immersion_mode'] = immersionMode; data['immersion_mode'] = immersionMode;
data['definitions'] = definitions; data['definitions'] = definitions;
data['translations'] = translations; data['translations'] = translations;
data['auto_igc'] = autoIGC;
return data; return data;
} }
@ -269,8 +275,10 @@ class PangeaRoomRules {
return immersionMode; return immersionMode;
case ToolSetting.definitions: case ToolSetting.definitions:
return definitions; return definitions;
case ToolSetting.translations: // case ToolSetting.translations:
return translations; // return translations;
case ToolSetting.autoIGC:
return autoIGC;
default: default:
throw Exception('Invalid key for setting permissions - $setting'); throw Exception('Invalid key for setting permissions - $setting');
} }
@ -298,7 +306,8 @@ enum ToolSetting {
interactiveGrammar, interactiveGrammar,
immersionMode, immersionMode,
definitions, definitions,
translations, // translations,
autoIGC,
} }
extension SettingCopy on ToolSetting { extension SettingCopy on ToolSetting {
@ -312,8 +321,10 @@ extension SettingCopy on ToolSetting {
return L10n.of(context)!.toggleImmersionMode; return L10n.of(context)!.toggleImmersionMode;
case ToolSetting.definitions: case ToolSetting.definitions:
return L10n.of(context)!.definitionsToolName; return L10n.of(context)!.definitionsToolName;
case ToolSetting.translations: // case ToolSetting.translations:
return L10n.of(context)!.messageTranslationsToolName; // return L10n.of(context)!.messageTranslationsToolName;
case ToolSetting.autoIGC:
return L10n.of(context)!.autoIGCToolName;
} }
} }
@ -328,8 +339,10 @@ extension SettingCopy on ToolSetting {
return L10n.of(context)!.toggleImmersionModeDesc; return L10n.of(context)!.toggleImmersionModeDesc;
case ToolSetting.definitions: case ToolSetting.definitions:
return L10n.of(context)!.definitionsToolDescription; return L10n.of(context)!.definitionsToolDescription;
case ToolSetting.translations: // case ToolSetting.translations:
return L10n.of(context)!.translationsToolDescrption; // return L10n.of(context)!.translationsToolDescrption;
case ToolSetting.autoIGC:
return L10n.of(context)!.autoIGCToolDescription;
} }
} }
} }

@ -1,19 +1,23 @@
import 'package:fluffychat/pangea/constants/model_keys.dart';
class LanguageDetection { class LanguageDetection {
String langCode; String langCode;
double confidence;
LanguageDetection({ LanguageDetection({
required this.langCode, required this.langCode,
required this.confidence,
}); });
factory LanguageDetection.fromJson(Map<String, dynamic> json) { factory LanguageDetection.fromJson(Map<String, dynamic> json) {
return LanguageDetection( return LanguageDetection(
langCode: json[_langCodeKey], langCode: json[ModelKey.langCode],
confidence: json[ModelKey.confidence],
); );
} }
static const _langCodeKey = "lang_code";
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
_langCodeKey: langCode, ModelKey.langCode: langCode,
ModelKey.confidence: confidence,
}; };
} }

@ -59,15 +59,17 @@ enum MatrixProfile {
interactiveGrammar, interactiveGrammar,
immersionMode, immersionMode,
definitions, definitions,
translations, // translations,
showedItInstructions, showedItInstructions,
showedClickMessage, showedClickMessage,
showedBlurMeansTranslate, showedBlurMeansTranslate,
showedTooltipInstructions,
createdAt, createdAt,
targetLanguage, targetLanguage,
sourceLanguage, sourceLanguage,
country, country,
publicProfile, publicProfile,
autoIGC,
} }
extension MatrixProfileExtension on MatrixProfile { extension MatrixProfileExtension on MatrixProfile {
@ -87,14 +89,18 @@ extension MatrixProfileExtension on MatrixProfile {
return ToolSetting.immersionMode.toString(); return ToolSetting.immersionMode.toString();
case MatrixProfile.definitions: case MatrixProfile.definitions:
return ToolSetting.definitions.toString(); return ToolSetting.definitions.toString();
case MatrixProfile.translations: // case MatrixProfile.translations:
return ToolSetting.translations.toString(); // return ToolSetting.translations.toString();
case MatrixProfile.autoIGC:
return ToolSetting.autoIGC.toString();
case MatrixProfile.showedItInstructions: case MatrixProfile.showedItInstructions:
return InstructionsEnum.itInstructions.toString(); return InstructionsEnum.itInstructions.toString();
case MatrixProfile.showedClickMessage: case MatrixProfile.showedClickMessage:
return InstructionsEnum.clickMessage.toString(); return InstructionsEnum.clickMessage.toString();
case MatrixProfile.showedBlurMeansTranslate: case MatrixProfile.showedBlurMeansTranslate:
return InstructionsEnum.blurMeansTranslate.toString(); return InstructionsEnum.blurMeansTranslate.toString();
case MatrixProfile.showedTooltipInstructions:
return InstructionsEnum.tooltipInstructions.toString();
case MatrixProfile.createdAt: case MatrixProfile.createdAt:
return ModelKey.userCreatedAt; return ModelKey.userCreatedAt;
case MatrixProfile.targetLanguage: case MatrixProfile.targetLanguage:

@ -1,13 +1,13 @@
import 'dart:convert'; import 'dart:convert';
import 'package:http/http.dart';
import 'package:fluffychat/pangea/config/environment.dart'; import 'package:fluffychat/pangea/config/environment.dart';
import 'package:fluffychat/pangea/models/language_detection_model.dart'; import 'package:fluffychat/pangea/models/language_detection_model.dart';
import 'package:fluffychat/pangea/models/lemma.dart'; import 'package:fluffychat/pangea/models/lemma.dart';
import 'package:fluffychat/pangea/models/pangea_match_model.dart'; import 'package:fluffychat/pangea/models/pangea_match_model.dart';
import 'package:fluffychat/pangea/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/models/pangea_token_model.dart';
import 'package:fluffychat/pangea/repo/span_data_repo.dart'; import 'package:fluffychat/pangea/repo/span_data_repo.dart';
import 'package:http/http.dart';
import '../constants/model_keys.dart'; import '../constants/model_keys.dart';
import '../models/igc_text_data_model.dart'; import '../models/igc_text_data_model.dart';
import '../network/requests.dart'; import '../network/requests.dart';
@ -39,7 +39,7 @@ class IgcRepo {
await Future.delayed(const Duration(seconds: 2)); await Future.delayed(const Duration(seconds: 2));
final IGCTextData igcTextData = IGCTextData( final IGCTextData igcTextData = IGCTextData(
detections: [LanguageDetection(langCode: "en")], detections: [LanguageDetection(langCode: "en", confidence: 0.99)],
tokens: [ tokens: [
PangeaToken( PangeaToken(
text: PangeaTokenText(content: "This", offset: 0, length: 4), text: PangeaTokenText(content: "This", offset: 0, length: 4),

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:fluffychat/pangea/constants/language_keys.dart'; import 'package:fluffychat/pangea/constants/language_keys.dart';
import 'package:fluffychat/pangea/constants/model_keys.dart'; import 'package:fluffychat/pangea/constants/model_keys.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
@ -10,6 +11,17 @@ import 'package:matrix/matrix.dart';
import '../../utils/matrix_sdk_extensions/matrix_locals.dart'; import '../../utils/matrix_sdk_extensions/matrix_locals.dart';
class GetChatListItemSubtitle { class GetChatListItemSubtitle {
final List<String> hideContentKeys = [
ModelKey.transcription,
];
bool moveBackInTimeline(Event event) =>
hideContentKeys.any(
(key) => event.content.tryGet(key) != null,
) ||
event.type.startsWith("p.") ||
event.type.startsWith("pangea.");
Future<String> getSubtitle( Future<String> getSubtitle(
L10n l10n, L10n l10n,
Event? event, Event? event,
@ -22,23 +34,14 @@ class GetChatListItemSubtitle {
eventContextId = null; eventContextId = null;
} }
final Timeline timeline = final Timeline timeline = await event.room.getTimeline(
await event.room.getTimeline(eventContextId: eventContextId); eventContextId: eventContextId,
);
if (event.content.tryGet(ModelKey.transcription) != null) {
int index = timeline.events.indexWhere(
(e) => e.eventId == event!.eventId,
);
while (index < timeline.events.length &&
(timeline.events[index].content.tryGet(ModelKey.transcription) !=
null ||
timeline.events[index].type != EventTypes.Message)) {
index++;
}
if (timeline.events.length > index + 1) { if (moveBackInTimeline(event)) {
event = timeline.events[index]; event = timeline.events.firstWhereOrNull((e) => !moveBackInTimeline(e));
if (event == null) {
return l10n.emptyChat;
} }
} }

@ -1,3 +1,4 @@
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
@ -102,6 +103,7 @@ enum InstructionsEnum {
itInstructions, itInstructions,
clickMessage, clickMessage,
blurMeansTranslate, blurMeansTranslate,
tooltipInstructions,
} }
extension Copy on InstructionsEnum { extension Copy on InstructionsEnum {
@ -113,6 +115,8 @@ extension Copy on InstructionsEnum {
return L10n.of(context)!.clickMessageTitle; return L10n.of(context)!.clickMessageTitle;
case InstructionsEnum.blurMeansTranslate: case InstructionsEnum.blurMeansTranslate:
return L10n.of(context)!.blurMeansTranslateTitle; return L10n.of(context)!.blurMeansTranslateTitle;
case InstructionsEnum.tooltipInstructions:
return L10n.of(context)!.tooltipInstructionsTitle;
} }
} }
@ -124,6 +128,10 @@ extension Copy on InstructionsEnum {
return L10n.of(context)!.clickMessageBody; return L10n.of(context)!.clickMessageBody;
case InstructionsEnum.blurMeansTranslate: case InstructionsEnum.blurMeansTranslate:
return L10n.of(context)!.blurMeansTranslateBody; return L10n.of(context)!.blurMeansTranslateBody;
case InstructionsEnum.tooltipInstructions:
return PlatformInfos.isMobile
? L10n.of(context)!.tooltipInstructionsMobileBody
: L10n.of(context)!.tooltipInstructionsBrowserBody;
} }
} }
} }

@ -3,6 +3,7 @@ import 'dart:developer';
import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart'; import 'package:fluffychat/pangea/matrix_event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/pangea/models/speech_to_text_models.dart'; import 'package:fluffychat/pangea/models/speech_to_text_models.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:fluffychat/pangea/utils/instructions.dart';
import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart'; import 'package:fluffychat/pangea/widgets/chat/toolbar_content_loading_indicator.dart';
import 'package:fluffychat/pangea/widgets/common/icon_number_widget.dart'; import 'package:fluffychat/pangea/widgets/common/icon_number_widget.dart';
import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart'; import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart';
@ -175,12 +176,24 @@ class MessageSpeechToTextCardState extends State<MessageSpeechToTextCard> {
number: number:
"${selectedToken?.confidence ?? speechToTextResponse!.transcript.confidence}%", "${selectedToken?.confidence ?? speechToTextResponse!.transcript.confidence}%",
toolTip: L10n.of(context)!.accuracy, toolTip: L10n.of(context)!.accuracy,
onPressed: () => MatrixState.pangeaController.instructions.show(
context,
InstructionsEnum.tooltipInstructions,
widget.messageEvent.eventId,
true,
),
), ),
IconNumberWidget( IconNumberWidget(
icon: Icons.speed, icon: Icons.speed,
number: number:
wordsPerMinuteString != null ? "$wordsPerMinuteString" : "??", wordsPerMinuteString != null ? "$wordsPerMinuteString" : "??",
toolTip: L10n.of(context)!.wordsPerMinute, toolTip: L10n.of(context)!.wordsPerMinute,
onPressed: () => MatrixState.pangeaController.instructions.show(
context,
InstructionsEnum.tooltipInstructions,
widget.messageEvent.eventId,
true,
),
), ),
], ],
), ),

@ -6,6 +6,7 @@ class IconNumberWidget extends StatelessWidget {
final Color? iconColor; final Color? iconColor;
final double? iconSize; final double? iconSize;
final String? toolTip; final String? toolTip;
final VoidCallback onPressed;
const IconNumberWidget({ const IconNumberWidget({
super.key, super.key,
@ -14,16 +15,20 @@ class IconNumberWidget extends StatelessWidget {
this.toolTip, this.toolTip,
this.iconColor, this.iconColor,
this.iconSize, this.iconSize,
required this.onPressed,
}); });
Widget _content(BuildContext context) { Widget _content(BuildContext context) {
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
Icon( IconButton(
icon, icon: Icon(
color: iconColor ?? Theme.of(context).iconTheme.color, icon,
size: iconSize ?? Theme.of(context).iconTheme.size, color: iconColor ?? Theme.of(context).iconTheme.color,
size: iconSize ?? Theme.of(context).iconTheme.size,
),
onPressed: onPressed,
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(

@ -839,9 +839,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"be": [ "be": [
@ -2279,9 +2288,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"bn": [ "bn": [
@ -3181,9 +3199,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"bo": [ "bo": [
@ -4083,9 +4110,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ca": [ "ca": [
@ -4985,9 +5021,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"cs": [ "cs": [
@ -5887,9 +5932,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"de": [ "de": [
@ -6736,9 +6790,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"el": [ "el": [
@ -7638,9 +7701,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"eo": [ "eo": [
@ -8540,17 +8612,35 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"es": [ "es": [
"suggestToChat", "suggestToChat",
"suggestToChatDesc", "suggestToChatDesc",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"et": [ "et": [
@ -9393,9 +9483,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"eu": [ "eu": [
@ -10238,9 +10337,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"fa": [ "fa": [
@ -11140,9 +11248,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"fi": [ "fi": [
@ -12042,9 +12159,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"fr": [ "fr": [
@ -12944,9 +13070,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ga": [ "ga": [
@ -13846,9 +13981,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"gl": [ "gl": [
@ -14691,9 +14835,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"he": [ "he": [
@ -15593,9 +15746,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"hi": [ "hi": [
@ -16495,9 +16657,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"hr": [ "hr": [
@ -17384,9 +17555,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"hu": [ "hu": [
@ -18286,9 +18466,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ia": [ "ia": [
@ -19712,9 +19901,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"id": [ "id": [
@ -20614,9 +20812,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ie": [ "ie": [
@ -21516,9 +21723,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"it": [ "it": [
@ -22403,9 +22619,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ja": [ "ja": [
@ -23305,9 +23530,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ko": [ "ko": [
@ -24207,9 +24441,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"lt": [ "lt": [
@ -25109,9 +25352,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"lv": [ "lv": [
@ -26011,9 +26263,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"nb": [ "nb": [
@ -26913,9 +27174,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"nl": [ "nl": [
@ -27815,9 +28085,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"pl": [ "pl": [
@ -28717,9 +28996,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"pt": [ "pt": [
@ -29619,9 +29907,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"pt_BR": [ "pt_BR": [
@ -30490,9 +30787,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"pt_PT": [ "pt_PT": [
@ -31392,9 +31698,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ro": [ "ro": [
@ -32294,9 +32609,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ru": [ "ru": [
@ -33139,9 +33463,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"sk": [ "sk": [
@ -34041,9 +34374,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"sl": [ "sl": [
@ -34943,9 +35285,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"sr": [ "sr": [
@ -35845,9 +36196,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"sv": [ "sv": [
@ -36712,9 +37072,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"ta": [ "ta": [
@ -37614,9 +37983,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"th": [ "th": [
@ -38516,9 +38894,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"tr": [ "tr": [
@ -39403,9 +39790,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"uk": [ "uk": [
@ -40248,9 +40644,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"vi": [ "vi": [
@ -41150,9 +41555,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"zh": [ "zh": [
@ -41995,9 +42409,18 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
], ],
"zh_Hant": [ "zh_Hant": [
@ -42897,8 +43320,17 @@
"roomDataMissing", "roomDataMissing",
"updatePhoneOS", "updatePhoneOS",
"wordsPerMinute", "wordsPerMinute",
"autoIGCToolName",
"autoIGCToolDescription",
"runGrammarCorrection",
"grammarCorrectionFailed",
"grammarCorrectionComplete",
"leaveRoomDescription", "leaveRoomDescription",
"archiveSpaceDescription", "archiveSpaceDescription",
"leaveSpaceDescription" "leaveSpaceDescription",
"onlyAdminDescription",
"tooltipInstructionsTitle",
"tooltipInstructionsMobileBody",
"tooltipInstructionsBrowserBody"
] ]
} }

Loading…
Cancel
Save