From 186982918d7275a97c3bcbb32a2db8429d8f2117 Mon Sep 17 00:00:00 2001 From: Gabby Gurdin Date: Wed, 21 Feb 2024 13:01:53 -0500 Subject: [PATCH] decoupling playing audio and sending audio event --- lib/pages/chat/events/audio_player.dart | 136 +++++-- lib/pangea/models/pangea_message_event.dart | 68 ++++ .../widgets/chat/message_audio_card.dart | 56 ++- needed-translations.txt | 368 +++++++++++++++--- 4 files changed, 535 insertions(+), 93 deletions(-) diff --git a/lib/pages/chat/events/audio_player.dart b/lib/pages/chat/events/audio_player.dart index 8617303b0..4c2b167ab 100644 --- a/lib/pages/chat/events/audio_player.dart +++ b/lib/pages/chat/events/audio_player.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:developer'; import 'dart:io'; +import 'package:fluffychat/pangea/widgets/chat/message_audio_card.dart'; import 'package:fluffychat/utils/error_reporter.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:flutter/foundation.dart'; @@ -14,13 +15,24 @@ import '../../../utils/matrix_sdk_extensions/event_extension.dart'; class AudioPlayerWidget extends StatefulWidget { final Color color; - final Event event; + // #Pangea + // final Event event; + final Event? event; + final PangeaAudioFile? matrixFile; + // Pangea# static String? currentId; static const int wavesCount = 40; - const AudioPlayerWidget(this.event, {this.color = Colors.black, super.key}); + const AudioPlayerWidget( + this.event, { + this.color = Colors.black, + // #Pangea + this.matrixFile, + // Pangea# + super.key, + }); @override AudioPlayerState createState() => AudioPlayerState(); @@ -58,16 +70,27 @@ class AudioPlayerState extends State { } Future _downloadAction() async { - if (status != AudioPlayerStatus.notDownloaded) return; + // #Pangea + // if (status != AudioPlayerStatus.notDownloaded) return; + if (status != AudioPlayerStatus.notDownloaded || widget.event == null) { + return; + } + // Pangea# setState(() => status = AudioPlayerStatus.downloading); try { - final matrixFile = await widget.event.downloadAndDecryptAttachment(); + // #Pangea + // final matrixFile = await widget.event.downloadAndDecryptAttachment(); + final matrixFile = await widget.event!.downloadAndDecryptAttachment(); + // Pangea# File? file; if (!kIsWeb) { final tempDir = await getTemporaryDirectory(); final fileName = Uri.encodeComponent( - widget.event.attachmentOrThumbnailMxcUrl()!.pathSegments.last, + // #Pangea + // widget.event.attachmentOrThumbnailMxcUrl()!.pathSegments.last, + widget.event!.attachmentOrThumbnailMxcUrl()!.pathSegments.last, + // Pangea# ); file = File('${tempDir.path}/${fileName}_${matrixFile.name}'); await file.writeAsBytes(matrixFile.bytes); @@ -94,14 +117,17 @@ class AudioPlayerState extends State { void _playAction() async { final audioPlayer = this.audioPlayer ??= AudioPlayer(); - if (AudioPlayerWidget.currentId != widget.event.eventId) { + // #Pangea + // if (AudioPlayerWidget.currentId != widget.event.eventId) { + // Pangea# + if (AudioPlayerWidget.currentId != widget.event?.eventId) { if (AudioPlayerWidget.currentId != null) { if (audioPlayer.playerState.playing) { await audioPlayer.stop(); setState(() {}); } } - AudioPlayerWidget.currentId = widget.event.eventId; + AudioPlayerWidget.currentId = widget.event?.eventId; } if (audioPlayer.playerState.playing) { await audioPlayer.pause(); @@ -136,27 +162,20 @@ class AudioPlayerState extends State { audioPlayer.setFilePath(audioFile.path); } else { // #Pangea - // final data = matrixFile!.bytes; - final mimeType = matrixFile!.mimeType; - //shouldn't have to be settting this here - //TODO: figure out why this is necessary - matrixFile = MatrixAudioFile( - bytes: matrixFile!.bytes, - name: matrixFile!.name, - mimeType: mimeType, - ); - debugPrint("audioType is $mimeType"); - // TODO - figure out why it's a wav at this point - // if (!TextToSpeechController.isOggFile(matrixFile!.bytes)) { - // debugger(when: kDebugMode); - // } else { - // debugPrint("still an ogg file!"); - // } try { - // Pangea# - await audioPlayer.setAudioSource(MatrixFileAudioSource(matrixFile!)); - // #Pangea - } catch (e, s) { + if (widget.matrixFile != null) { + await audioPlayer.setAudioSource( + BytesAudioSource( + widget.matrixFile!.bytes, + widget.matrixFile!.mimeType, + ), + ); + } else { + // Pangea# + await audioPlayer.setAudioSource(MatrixFileAudioSource(matrixFile!)); + // #Pangea + } + } catch (e, _) { debugger(when: kDebugMode); } // Pangea# @@ -170,18 +189,32 @@ class AudioPlayerState extends State { static const double buttonSize = 36; String? get _durationString { - final durationInt = widget.event.content - .tryGetMap('info') - ?.tryGet('duration'); + // #Pangea + int? durationInt; + if (widget.matrixFile?.duration != null) { + durationInt = widget.matrixFile!.duration; + } else { + // final durationInt = widget.event?.content + durationInt = widget.event?.content + .tryGetMap('info') + ?.tryGet('duration'); + } + // Pangea# if (durationInt == null) return null; final duration = Duration(milliseconds: durationInt); return '${duration.inMinutes.toString().padLeft(2, '0')}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}'; } List _getWaveform() { - final eventWaveForm = widget.event.content - .tryGetMap('org.matrix.msc1767.audio') - ?.tryGetList('waveform'); + // #Pangea + final eventWaveForm = widget.matrixFile?.waveform ?? + widget.event?.content + .tryGetMap('org.matrix.msc1767.audio') + ?.tryGetList('waveform'); + // final eventWaveForm = widget.event?.content + // .tryGetMap('org.matrix.msc1767.audio') + // ?.tryGetList('waveform'); + // Pangea# if (eventWaveForm == null || eventWaveForm.isEmpty) { return List.filled(AudioPlayerWidget.wavesCount, 500); } @@ -205,6 +238,20 @@ class AudioPlayerState extends State { void initState() { super.initState(); waveform = _getWaveform(); + // #Pangea + if (widget.matrixFile != null) { + if (!kIsWeb) { + getTemporaryDirectory().then((val) { + final tempDir = val; + final file = File('${tempDir.path}/${widget.matrixFile!.name}'); + file.writeAsBytesSync(widget.matrixFile!.bytes); + audioFile = file; + }); + } + status = AudioPlayerStatus.downloaded; + setState(() {}); + } + // Pangea# } @override @@ -233,7 +280,7 @@ class AudioPlayerState extends State { color: widget.color, ), ), - onLongPress: () => widget.event.saveFile(context), + onLongPress: () => widget.event?.saveFile(context), onTap: () { if (status == AudioPlayerStatus.downloaded) { _playAction(); @@ -313,3 +360,24 @@ class MatrixFileAudioSource extends StreamAudioSource { ); } } + +// #Pangea +class BytesAudioSource extends StreamAudioSource { + final Uint8List bytes; + final String mimeType; + BytesAudioSource(this.bytes, this.mimeType); + + @override + Future request([int? start, int? end]) async { + start ??= 0; + end ??= bytes.length; + return StreamAudioResponse( + sourceLength: bytes.length, + contentLength: end - start, + offset: start, + stream: Stream.value(bytes.sublist(start, end)), + contentType: mimeType, + ); + } +} +// Pangea# diff --git a/lib/pangea/models/pangea_message_event.dart b/lib/pangea/models/pangea_message_event.dart index 9e130766a..32a0baf8a 100644 --- a/lib/pangea/models/pangea_message_event.dart +++ b/lib/pangea/models/pangea_message_event.dart @@ -10,6 +10,7 @@ import 'package:fluffychat/pangea/models/class_model.dart'; import 'package:fluffychat/pangea/models/message_data_models.dart'; import 'package:fluffychat/pangea/models/pangea_representation_event.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; +import 'package:fluffychat/pangea/widgets/chat/message_audio_card.dart'; import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; @@ -82,6 +83,73 @@ class PangeaMessageEvent { return true; } + Future getMatrixAudioFile(String langCode) async { + final String text = representationByLanguage(langCode)?.text ?? body; + final TextToSpeechRequest params = TextToSpeechRequest( + text: text, + langCode: langCode, + ); + + final TextToSpeechResponse response = + await MatrixState.pangeaController.textToSpeech.get( + params, + ); + + final audioBytes = base64.decode(response.audioContent); + final eventIdParam = _event.eventId; + final fileName = + "audio_for_${eventIdParam}_$langCode.${response.fileExtension}"; + + final file = PangeaAudioFile( + bytes: audioBytes, + name: fileName, + mimeType: response.mimeType, + duration: response.durationMillis, + waveform: response.waveform, + ); + + sendAudioEvent(file, response, text, langCode); + + return file; + } + + Future sendAudioEvent( + PangeaAudioFile file, + TextToSpeechResponse response, + String text, + String langCode, + ) async { + final String? eventId = await room.sendFileEvent( + file, + inReplyTo: _event, + extraContent: { + 'info': { + ...file.info, + 'duration': response.durationMillis, + }, + 'org.matrix.msc3245.voice': {}, + 'org.matrix.msc1767.audio': { + 'duration': response.durationMillis, + 'waveform': response.waveform, + }, + ModelKey.transcription: { + ModelKey.text: text, + ModelKey.langCode: langCode, + }, + }, + ); + + debugPrint("eventId in getAudioGlobal $eventId"); + final Event? audioEvent = + eventId != null ? await room.getEventById(eventId) : null; + + if (audioEvent == null) { + return null; + } + allAudio.add(audioEvent); + return audioEvent; + } + //get audio for text and language //if no audio exists, create it //if audio exists, return it diff --git a/lib/pangea/widgets/chat/message_audio_card.dart b/lib/pangea/widgets/chat/message_audio_card.dart index 05f8ffee2..d86539cb7 100644 --- a/lib/pangea/widgets/chat/message_audio_card.dart +++ b/lib/pangea/widgets/chat/message_audio_card.dart @@ -21,17 +21,36 @@ class MessageAudioCard extends StatefulWidget { class MessageAudioCardState extends State { bool _isLoading = false; Event? localAudioEvent; + PangeaAudioFile? audioFile; - void fetchAudio() { + Future fetchAudio() async { if (!mounted) return; setState(() => _isLoading = true); - widget.messageEvent - .getAudioGlobal(widget.messageEvent.messageDisplayLangCode) - .then((Event? event) { - localAudioEvent = event; - }).catchError((e) { + // first, try to get the audio event + // if there's not audio event, then call the API + // Then, if on mobile, save it to a temp file and use that as audio source + // If on web, stream the audio bytes + + try { + final String langCode = widget.messageEvent.messageDisplayLangCode; + final String? text = + widget.messageEvent.representationByLanguage(langCode)?.text; + if (text != null) { + final Event? localEvent = + widget.messageEvent.getAudioLocal(langCode, text); + if (localEvent != null) { + localAudioEvent = localEvent; + if (mounted) setState(() => _isLoading = false); + return; + } + } + + audioFile = await widget.messageEvent.getMatrixAudioFile(langCode); + if (mounted) setState(() => _isLoading = false); + } catch (e, _) { debugPrint(StackTrace.current.toString()); - if (!mounted) return null; + if (!mounted) return; + setState(() => _isLoading = false); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(L10n.of(context)!.errorGettingAudio), @@ -46,10 +65,8 @@ class MessageAudioCardState extends State { widget.messageEvent.messageDisplayLangCode, }, ); - return null; - }).whenComplete(() { - if (mounted) setState(() => _isLoading = false); - }); + } + return; } @override @@ -85,7 +102,7 @@ class MessageAudioCardState extends State { color: Theme.of(context).colorScheme.primary, ), ) - : localAudioEvent != null + : localAudioEvent != null || audioFile != null ? Container( constraints: const BoxConstraints( maxWidth: 250, @@ -93,8 +110,9 @@ class MessageAudioCardState extends State { child: Column( children: [ AudioPlayerWidget( - localAudioEvent!, + localAudioEvent, color: Theme.of(context).colorScheme.onPrimaryContainer, + matrixFile: audioFile, ), ], ), @@ -106,3 +124,15 @@ class MessageAudioCardState extends State { ); } } + +class PangeaAudioFile extends MatrixAudioFile { + List? waveform; + + PangeaAudioFile({ + required super.bytes, + required super.name, + super.mimeType, + super.duration, + this.waveform, + }); +} diff --git a/needed-translations.txt b/needed-translations.txt index 72d449649..ce3531669 100644 --- a/needed-translations.txt +++ b/needed-translations.txt @@ -809,7 +809,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "bn": [ @@ -1637,7 +1643,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "bo": [ @@ -2465,7 +2477,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "ca": [ @@ -3293,7 +3311,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "cs": [ @@ -4121,7 +4145,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "de": [ @@ -4918,7 +4948,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "el": [ @@ -5746,7 +5782,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "eo": [ @@ -6574,14 +6616,26 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "es": [ "errorGettingAudio", "define", "listen", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "et": [ @@ -7394,7 +7448,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "eu": [ @@ -8191,7 +8251,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "fa": [ @@ -9019,7 +9085,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "fi": [ @@ -9847,7 +9919,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "fr": [ @@ -10675,7 +10753,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "ga": [ @@ -11503,7 +11587,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "gl": [ @@ -12300,7 +12390,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "he": [ @@ -13128,7 +13224,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "hi": [ @@ -13956,7 +14058,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "hr": [ @@ -14771,7 +14879,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "hu": [ @@ -15599,7 +15713,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "id": [ @@ -16427,7 +16547,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "ie": [ @@ -17255,7 +17381,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "it": [ @@ -18068,7 +18200,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "ja": [ @@ -18896,7 +19034,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "ko": [ @@ -19724,7 +19868,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "lt": [ @@ -20552,7 +20702,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "lv": [ @@ -21380,7 +21536,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "nb": [ @@ -22208,7 +22370,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "nl": [ @@ -23036,7 +23204,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "pl": [ @@ -23864,7 +24038,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "pt": [ @@ -24692,7 +24872,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "pt_BR": [ @@ -25489,7 +25675,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "pt_PT": [ @@ -26317,7 +26509,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "ro": [ @@ -27145,7 +27343,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "ru": [ @@ -27946,7 +28150,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "sk": [ @@ -28774,7 +28984,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "sl": [ @@ -29602,7 +29818,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "sr": [ @@ -30430,7 +30652,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "sv": [ @@ -31258,7 +31486,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "ta": [ @@ -32086,7 +32320,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "th": [ @@ -32914,7 +33154,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "tr": [ @@ -33727,7 +33973,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "uk": [ @@ -34540,7 +34792,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "vi": [ @@ -35368,7 +35626,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "zh": [ @@ -36181,7 +36445,13 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ], "zh_Hant": [ @@ -37009,6 +37279,12 @@ "enableModeration", "enableModerationDesc", "conversationLanguageLevel", - "showDefinition" + "showDefinition", + "acceptedKeyVerification", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification" ] }