diff --git a/assets/blodeuwedd.png b/assets/blodeuwedd.png new file mode 100644 index 00000000..361b6a34 Binary files /dev/null and b/assets/blodeuwedd.png differ diff --git a/lib/cwtch/cwtch.dart b/lib/cwtch/cwtch.dart index a287baac..6dbb6f29 100644 --- a/lib/cwtch/cwtch.dart +++ b/lib/cwtch/cwtch.dart @@ -133,4 +133,9 @@ abstract class Cwtch { Future GetDebugInfo(); bool IsServersCompiled(); + + Future SummarizeConversation(String profile, int conversation); + Future TranslateMessage(String profile, int conversation, int message, String language); + + bool IsBlodeuweddSupported(); } diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index d55cdea2..ca268689 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -408,6 +408,16 @@ class CwtchNotifier { case "DoneStorageMigration": appState.SetModalState(ModalState.none); break; + case "BlodeuweddSummary": + var identifier = int.parse(data["ConversationID"]); + profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)?.updateSummaryEvent(data["Summary"]); + break; + case "BlodeuweddTranslation": + var identifier = int.parse(data["ConversationID"]); + var mid = int.parse(data["Index"]); + EnvironmentConfig.debugLog("received translation event: $identifier $mid $data"); + profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)?.updateTranslationEvent(mid, data["Translation"]); + break; case "ACNInfo": var key = data["Key"]; var handle = data["Handle"]; diff --git a/lib/cwtch/ffi.dart b/lib/cwtch/ffi.dart index c7f25be4..8b601eed 100644 --- a/lib/cwtch/ffi.dart +++ b/lib/cwtch/ffi.dart @@ -72,6 +72,16 @@ typedef GetJsonBlobFromStrStrIntFn = Pointer Function(Pointer, int, typedef get_json_blob_from_str_int_function = Pointer Function(Pointer, Int32, Int32); typedef GetJsonBlobFromStrIntFn = Pointer Function(Pointer, int, int); +typedef get_json_blob_from_str_int_int_str_function = Pointer Function(Pointer, Int32, Int32, Int32, Pointer, Int32); +typedef GetJsonBlobFromStrIntIntStrFn = Pointer Function( + Pointer, + int, + int, + int, + Pointer, + int, +); + typedef get_json_blob_from_str_int_int_function = Pointer Function(Pointer, Int32, Int32, Int32); typedef GetJsonBlobFromStrIntIntFn = Pointer Function(Pointer, int, int, int); @@ -903,4 +913,53 @@ class CwtchFfi implements Cwtch { bool IsServersCompiled() { return library.providesSymbol("c_LoadServers"); } + + @override + Future SummarizeConversation(String profile, int conversation) async { + if (!library.providesSymbol("c_Summarize")) { + return Future.value(""); + } + var summarize = library.lookup>("c_Summarize"); + // ignore: non_constant_identifier_names + final SummarizeFn = summarize.asFunction(); + final utf8profile = profile.toNativeUtf8(); + Pointer jsonMessageBytes = SummarizeFn(utf8profile, utf8profile.length, conversation); + String jsonMessage = jsonMessageBytes.toDartString(); + _UnsafeFreePointerAnyUseOfThisFunctionMustBeDoubleApproved(jsonMessageBytes); + malloc.free(utf8profile); + return jsonMessage; + } + + @override + Future TranslateMessage(String profile, int conversation, int message, String language) async { + if (!library.providesSymbol("c_Translate")) { + return Future.value(""); + } + var translate = library.lookup>("c_Translate"); + // ignore: non_constant_identifier_names + final TranslateFn = translate.asFunction(); + final utf8profile = profile.toNativeUtf8(); + final utf8lang = language.toNativeUtf8(); + Pointer jsonMessageBytes = TranslateFn( + utf8profile, + utf8profile.length, + conversation, + message, + utf8lang, + utf8lang.length, + ); + String jsonMessage = jsonMessageBytes.toDartString(); + _UnsafeFreePointerAnyUseOfThisFunctionMustBeDoubleApproved(jsonMessageBytes); + malloc.free(utf8profile); + malloc.free(utf8lang); + return jsonMessage; + } + + @override + bool IsBlodeuweddSupported() { + if (library.providesSymbol("c_Translate")) { + return true; + } + return false; + } } diff --git a/lib/cwtch/gomobile.dart b/lib/cwtch/gomobile.dart index 24477318..78d56b5c 100644 --- a/lib/cwtch/gomobile.dart +++ b/lib/cwtch/gomobile.dart @@ -370,4 +370,22 @@ class CwtchGomobile implements Cwtch { // never for android builds... return false; } + + @override + Future SummarizeConversation(String profile, int conversation) { + // TODO: implement SummarizeConversation + throw UnimplementedError(); + } + + @override + Future TranslateMessage(String profile, int conversation, int message, String language) { + // TODO: implement TranslateMessage + throw UnimplementedError(); + } + + @override + bool IsBlodeuweddSupported() { + // Blodeuwedd is not currently supported on lower end devices. + return false; + } } diff --git a/lib/l10n/intl_cy.arb b/lib/l10n/intl_cy.arb index 42d579c0..998c8fa1 100644 --- a/lib/l10n/intl_cy.arb +++ b/lib/l10n/intl_cy.arb @@ -1,6 +1,14 @@ { "@@locale": "cy", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_da.arb b/lib/l10n/intl_da.arb index 65b4b793..0eb5d4a8 100644 --- a/lib/l10n/intl_da.arb +++ b/lib/l10n/intl_da.arb @@ -1,6 +1,14 @@ { "@@locale": "da", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb index 9e5a62e6..6b07ef5c 100644 --- a/lib/l10n/intl_de.arb +++ b/lib/l10n/intl_de.arb @@ -1,8 +1,16 @@ { "@@locale": "de", - "@@last_modified": "2023-03-14T14:10:01+01:00", - "localeKo": "Korean \/ 한국어", - "localeSk": "Slovak \/ Slovák", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", + "localeSk": "Slowakisch \/ Slovák", + "localeKo": "Koreanisch \/ 한국어", "profileAutostartLabel": "Autostart", "profileEnabled": "Aktivieren", "profileAutostartDescription": "Legt fest, ob das Profil beim Starten automatisch gestartet wird", diff --git a/lib/l10n/intl_el.arb b/lib/l10n/intl_el.arb index 503f5c4b..d7662a9b 100644 --- a/lib/l10n/intl_el.arb +++ b/lib/l10n/intl_el.arb @@ -1,6 +1,14 @@ { "@@locale": "el", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index ae686841..ed694fe9 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1,6 +1,14 @@ { "@@locale": "en", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddTranslate": "Translate Message", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_es.arb b/lib/l10n/intl_es.arb index 9ed254ad..54c5c3d2 100644 --- a/lib/l10n/intl_es.arb +++ b/lib/l10n/intl_es.arb @@ -1,6 +1,14 @@ { "@@locale": "es", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index c7abed64..25cb0f8a 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -1,6 +1,14 @@ { "@@locale": "fr", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_it.arb b/lib/l10n/intl_it.arb index dfe40430..7dfc262c 100644 --- a/lib/l10n/intl_it.arb +++ b/lib/l10n/intl_it.arb @@ -1,6 +1,14 @@ { "@@locale": "it", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_ko.arb b/lib/l10n/intl_ko.arb index 06d5fba8..a328e7dc 100644 --- a/lib/l10n/intl_ko.arb +++ b/lib/l10n/intl_ko.arb @@ -1,6 +1,23 @@ { "@@locale": "ko", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", + "labelACNCircuitInfo": "ACN 회로 정보", + "clickableLinksWarning": "이 URL을 열면 Cwtch 외부에서 응용 프로그램이 시작되고 메타데이터가 노출되거나 Cwtch의 보안이 손상될 수 있습니다. 신뢰할 수 있는 사용자의 URL만 엽니다. 계속하시겠습니까?", + "thisFeatureRequiresGroupExpermientsToBeEnabled": "이 기능을 사용하려면 설정에서 그룹 실험을 사용하도록 설정해야 합니다.", + "loadingCwtch": "Cwtch 로드 중...", + "msgConfirmSend": "보내시겠습니까?", + "torSettingsUseCustomTorServiceConfiguration": "사용자 지정 Tor 서비스 구성(torrc) 사용", + "tooltipSelectACustomProfileImage": "사용자 정의 프로필 이미지 선택", + "exportProfileTooltip": "이 프로필을 암호화된 파일에 백업하십시오. 암호화된 파일을 다른 Cwtch 앱으로 가져올 수 있습니다.", + "settingAndroidPowerExemption": "안드로이드는 배터리 최적화를 무시합니다.", "deleteServerSuccess": "서버를 성공적으로 삭제했습니다.", "localeRU": "러시아어 \/ Русский", "newMessagesLabel": "새로운 메시지", @@ -95,11 +112,7 @@ "tooltipStrikethrough": "Strikethrough", "tooltipItalicize": "Italic", "tooltipBoldText": "Bold", - "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", - "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", - "clickableLinksWarning": "Opening this URL will launch an application outside of Cwtch and may reveal metadata or otherwise compromise the security of Cwtch. Only open URLs from people you trust. Are you sure you want to continue?", - "exportProfileTooltip": "Backup this profile to an encrypted file. The encrypted file can be imported into another Cwtch app.", "notificationContentSimpleEvent": "Plain Event", "conversationNotificationPolicySettingDescription": "Control notification behaviour for this conversation", "conversationNotificationPolicySettingLabel": "Conversation Notification Policy", @@ -111,15 +124,12 @@ "conversationNotificationPolicyDefault": "Default", "notificationPolicyDefaultAll": "Default All", "notificationPolicyMute": "Mute", - "tooltipSelectACustomProfileImage": "Select a Custom Profile Image", "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", "torSettingsEnableCache": "Cache Tor Consensus", "descriptionACNCircuitInfo": "In depth information about the path that the anonymous communication network is using to connect to this conversation.", - "labelACNCircuitInfo": "ACN Circuit Info", "fileSharingSettingsDownloadFolderTooltip": "Browse to select a different default folder for downloaded files.", "fileSharingSettingsDownloadFolderDescription": "When files are downloaded automatically (e.g. image files, when image previews are enabled) a default location to download the files to is needed.", "torSettingsUseCustomTorServiceConfigurastionDescription": "Override the default tor configuration. Warning: This could be dangerous. Only turn this on if you know what you are doing.", - "torSettingsUseCustomTorServiceConfiguration": "Use a Custom Tor Service Configuration (torrc)", "torSettingsCustomControlPortDescription": "Use a custom port for control connections to the Tor proxy", "torSettingsCustomControlPort": "Custom Control Port", "torSettingsCustomSocksPortDescription": "Use a custom port for data connections to the Tor proxy", @@ -127,9 +137,7 @@ "torSettingsEnabledAdvancedDescription": "Use an existing Tor service on your system, or change the parameters of the Cwtch Tor Service", "torSettingsEnabledAdvanced": "Enable Advanced Tor Configuration", "msgAddToAccept": "Add this account to your contacts in order to accept this file.", - "msgConfirmSend": "Are you sure you want to send", "storageMigrationModalMessage": "Migrating profiles to new storage format. This could take a few minutes...", - "loadingCwtch": "Loading Cwtch...", "themeNameMidnight": "Midnight", "themeNameMermaid": "Mermaid", "themeNameGhost": "Ghost", diff --git a/lib/l10n/intl_lb.arb b/lib/l10n/intl_lb.arb index e0ecffbf..7861d0b8 100644 --- a/lib/l10n/intl_lb.arb +++ b/lib/l10n/intl_lb.arb @@ -1,6 +1,14 @@ { "@@locale": "lb", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_nl.arb b/lib/l10n/intl_nl.arb index ef60efb6..19ff7488 100644 --- a/lib/l10n/intl_nl.arb +++ b/lib/l10n/intl_nl.arb @@ -1,6 +1,14 @@ { "@@locale": "nl", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "profileAutostartDescription": "Regelt of het profiel automatisch wordt gestart bij het opstarten", "profileAutostartLabel": "Automatisch starten", diff --git a/lib/l10n/intl_no.arb b/lib/l10n/intl_no.arb index 3dec6207..346146ed 100644 --- a/lib/l10n/intl_no.arb +++ b/lib/l10n/intl_no.arb @@ -1,6 +1,14 @@ { "@@locale": "no", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_pl.arb b/lib/l10n/intl_pl.arb index 9350a3f6..339aa25f 100644 --- a/lib/l10n/intl_pl.arb +++ b/lib/l10n/intl_pl.arb @@ -1,6 +1,14 @@ { "@@locale": "pl", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_pt.arb b/lib/l10n/intl_pt.arb index 9bc50238..2bb91d9d 100644 --- a/lib/l10n/intl_pt.arb +++ b/lib/l10n/intl_pt.arb @@ -1,6 +1,14 @@ { "@@locale": "pt", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_pt_BR.arb b/lib/l10n/intl_pt_BR.arb index 85d24e2b..809899dd 100644 --- a/lib/l10n/intl_pt_BR.arb +++ b/lib/l10n/intl_pt_BR.arb @@ -1,6 +1,14 @@ { "@@locale": "pt_BR", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_ro.arb b/lib/l10n/intl_ro.arb index 47e08c3e..dfc274e6 100644 --- a/lib/l10n/intl_ro.arb +++ b/lib/l10n/intl_ro.arb @@ -1,6 +1,14 @@ { "@@locale": "ro", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb index d967a9c9..70375987 100644 --- a/lib/l10n/intl_ru.arb +++ b/lib/l10n/intl_ru.arb @@ -1,6 +1,14 @@ { "@@locale": "ru", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Start or stop the profile", diff --git a/lib/l10n/intl_sk.arb b/lib/l10n/intl_sk.arb index 3c69a59c..15806e78 100644 --- a/lib/l10n/intl_sk.arb +++ b/lib/l10n/intl_sk.arb @@ -1,6 +1,14 @@ { "@@locale": "sk", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "deleteBtn": " Vymazať", diff --git a/lib/l10n/intl_tr.arb b/lib/l10n/intl_tr.arb index c703eb76..1f806ed4 100644 --- a/lib/l10n/intl_tr.arb +++ b/lib/l10n/intl_tr.arb @@ -1,6 +1,14 @@ { "@@locale": "tr", - "@@last_modified": "2023-03-14T14:10:01+01:00", + "@@last_modified": "2023-03-27T20:38:31+02:00", + "blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.", + "blodeuweddProcessing": "Blodeuwedd is processing...", + "blodeuweddTranslate": "Translate Message", + "blodeuweddSummarize": "Summarize Conversation", + "blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.", + "blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.", + "blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.", + "blodeuweddExperimentEnable": "Blodeuwedd Assistant", "localeKo": "Korean \/ 한국어", "localeSk": "Slovak \/ Slovák", "profileEnabledDescription": "Profili başlat veya durdur", diff --git a/lib/models/contact.dart b/lib/models/contact.dart index 2ed4901f..0589957d 100644 --- a/lib/models/contact.dart +++ b/lib/models/contact.dart @@ -2,6 +2,7 @@ import 'package:cwtch/main.dart'; import 'package:cwtch/models/message_draft.dart'; import 'package:cwtch/models/profile.dart'; import 'package:cwtch/widgets/messagerow.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; @@ -343,4 +344,15 @@ class ContactInfoState extends ChangeNotifier { bool isAccepted() { return _accepted && !_blocked; } + + String summary = ""; + void updateSummaryEvent(String summary) { + this.summary += summary; + notifyListeners(); + } + + void updateTranslationEvent(int messageID, String translation) { + this.messageCache.updateTranslationEvent(messageID, translation); + notifyListeners(); + } } diff --git a/lib/models/message.dart b/lib/models/message.dart index 68721bc7..316e0fbf 100644 --- a/lib/models/message.dart +++ b/lib/models/message.dart @@ -316,6 +316,12 @@ class MessageMetadata extends ChangeNotifier { bool get ackd => this._ackd; + String translation = ""; + void updateTranslationEvent(String translation) { + this.translation += translation; + notifyListeners(); + } + set ackd(bool newVal) { this._ackd = newVal; notifyListeners(); diff --git a/lib/models/messagecache.dart b/lib/models/messagecache.dart index 0145689d..b1807a0a 100644 --- a/lib/models/messagecache.dart +++ b/lib/models/messagecache.dart @@ -176,10 +176,19 @@ class MessageCache extends ChangeNotifier { notifyListeners(); } + void notifyUpdate(int messageID) { + notifyListeners(); + } + int size() { // very naive cache size, assuming MessageInfo are fairly large on average // and everything else is small in comparison int cacheSize = cache.entries.map((e) => e.value.size()).fold(0, (previousValue, element) => previousValue + element); return cacheSize + cacheByHash.length * 64 + cacheByIndex.length * 16; } + + void updateTranslationEvent(int messageID, String translation) { + cache[messageID]?.metadata.updateTranslationEvent(translation); + notifyListeners(); + } } diff --git a/lib/settings.dart b/lib/settings.dart index 91af7cc2..956fd5b9 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -16,6 +16,7 @@ const ImagePreviewsExperiment = "filesharing-images"; const ClickableLinksExperiment = "clickable-links"; const FormattingExperiment = "message-formatting"; const QRCodeExperiment = "qrcode-support"; +const BlodeuweddExperiment = "blodeuwedd"; enum DualpaneMode { Single, @@ -137,6 +138,7 @@ class Settings extends ChangeNotifier { // auto-download folder _downloadPath = settings["DownloadPath"] ?? ""; + _blodeuweddPath = settings["BlodeuweddPath"] ?? ""; // allow a custom tor config _allowAdvancedTorConfig = settings["AllowAdvancedTorConfig"] ?? false; @@ -409,6 +411,13 @@ class Settings extends ChangeNotifier { /// Construct a default settings object. Settings(this.locale, this.theme); + String _blodeuweddPath = ""; + String get blodeuweddPath => _blodeuweddPath; + set blodeuweddPath(String newval) { + _blodeuweddPath = newval; + notifyListeners(); + } + /// Convert this Settings object to a JSON representation for serialization on the /// event bus. dynamic asJson() { @@ -435,7 +444,8 @@ class Settings extends ChangeNotifier { "CustomControlPort": _controlPort, "CustomAuth": _customTorAuth, "UseTorCache": _useTorCache, - "TorCacheDir": _torCacheDir + "TorCacheDir": _torCacheDir, + "BlodeuweddPath": _blodeuweddPath }; } } diff --git a/lib/third_party/linkify/uri.dart b/lib/third_party/linkify/uri.dart index 89808789..c8df7841 100644 --- a/lib/third_party/linkify/uri.dart +++ b/lib/third_party/linkify/uri.dart @@ -36,16 +36,11 @@ final _urlRegex = RegExp( ); final _looseUrlRegex = RegExp( - r'^(.*?)((https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*))', + r'^(.*?)((https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,16}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*))', caseSensitive: false, dotAll: true, ); -final _protocolIdentifierRegex = RegExp( - r'^(https?:\/\/)', - caseSensitive: false, -); - class Formatter { final RegExp expression; final LinkifyElement Function(String) element; diff --git a/lib/views/globalsettingsview.dart b/lib/views/globalsettingsview.dart index 0a75d8d0..fda4ca89 100644 --- a/lib/views/globalsettingsview.dart +++ b/lib/views/globalsettingsview.dart @@ -460,6 +460,41 @@ class _GlobalSettingsViewState extends State { ), ]), ), + SwitchListTile( + title: Text(AppLocalizations.of(context)!.blodeuweddExperimentEnable, style: TextStyle(color: settings.current().mainTextColor)), + subtitle: Provider.of(context, listen: false).cwtch.IsBlodeuweddSupported() + ? Text(AppLocalizations.of(context)!.blodeuweddDescription) + : Text(AppLocalizations.of(context)!.blodeuweddNotSupported), + value: Provider.of(context, listen: false).cwtch.IsBlodeuweddSupported() && settings.isExperimentEnabled(BlodeuweddExperiment), + onChanged: Provider.of(context, listen: false).cwtch.IsBlodeuweddSupported() + ? (bool value) { + if (value) { + settings.enableExperiment(BlodeuweddExperiment); + } else { + settings.disableExperiment(BlodeuweddExperiment); + } + saveSettings(context); + } + : null, + activeTrackColor: settings.theme.defaultButtonColor, + inactiveTrackColor: settings.theme.defaultButtonDisabledColor, + inactiveThumbColor: settings.theme.defaultButtonDisabledColor, + secondary: Icon(Icons.assistant, color: settings.current().mainTextColor), + ), + Visibility( + visible: Provider.of(context, listen: false).cwtch.IsBlodeuweddSupported() && settings.isExperimentEnabled(BlodeuweddExperiment), + child: CwtchFolderPicker( + testKey: Key("DownloadFolderPicker"), + label: AppLocalizations.of(context)!.settingDownloadFolder, + initialValue: settings.blodeuweddPath, + description: AppLocalizations.of(context)!.blodeuweddPath, + tooltip: AppLocalizations.of(context)!.blodeuweddPath, + onSave: (newVal) { + settings.blodeuweddPath = newVal; + saveSettings(context); + }, + ), + ), ], )), Visibility( diff --git a/lib/views/messageview.dart b/lib/views/messageview.dart index 1312078a..99cb011f 100644 --- a/lib/views/messageview.dart +++ b/lib/views/messageview.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:math'; @@ -16,8 +17,10 @@ import 'package:cwtch/models/profile.dart'; import 'package:cwtch/third_party/linkify/flutter_linkify.dart'; import 'package:cwtch/widgets/malformedbubble.dart'; import 'package:cwtch/widgets/messageloadingbubble.dart'; +import 'package:cwtch/widgets/messagerow.dart'; import 'package:cwtch/widgets/profileimage.dart'; import 'package:cwtch/controllers/filesharing.dart' as filesharing; +import 'package:cwtch/widgets/staticmessagebubble.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; @@ -50,7 +53,7 @@ class _MessageViewState extends State { File? imagePreview; bool showDown = false; bool showPreview = false; - + final scaffoldKey = GlobalKey(); // <---- Another instance variable @override void initState() { scrollListener.itemPositions.addListener(() { @@ -107,6 +110,22 @@ class _MessageViewState extends State { splashRadius: Material.defaultSplashRadius / 2, icon: Icon(CwtchIcons.manage_files), tooltip: AppLocalizations.of(context)!.manageSharedFiles, onPressed: _pushFileSharingSettings)); } + var profile = Provider.of(context, listen: false).profileOnion; + var conversation = Provider.of(context, listen: false).identifier; + + if (Provider.of(context, listen: false).cwtch.IsBlodeuweddSupported() && Provider.of(context).isExperimentEnabled(BlodeuweddExperiment)) { + appBarButtons.add(IconButton( + splashRadius: Material.defaultSplashRadius / 2, + icon: Icon(Icons.summarize), + tooltip: AppLocalizations.of(context)!.blodeuweddSummarize, + onPressed: () async { + Provider.of(context, listen: false).summary = ""; + Provider.of(context, listen: false).updateSummaryEvent(""); + Provider.of(context, listen: false).cwtch.SummarizeConversation(profile, conversation); + _summarizeConversation(context, Provider.of(context, listen: false), Provider.of(context, listen: false)); + })); + } + if (Provider.of(context).isOnline()) { if (showFileSharing) { appBarButtons.add(IconButton( @@ -824,3 +843,57 @@ class _MessageViewState extends State { }); } } + +void _summarizeConversation(BuildContext context, ProfileInfoState profile, Settings settings) async { + showModalBottomSheet( + builder: ( + BuildContext bcontext, + ) { + return StatefulBuilder(builder: (BuildContext scontext, StateSetter setState /*You can rename this!*/) { + if (scontext.mounted) { + new Timer.periodic(Duration(seconds: 1), (Timer t) { + if (scontext.mounted) { + setState(() {}); + } + }); + } + + var bubble = StaticMessageBubble( + profile, + settings, + MessageMetadata(profile.onion, Provider.of(context).identifier, 1, DateTime.now(), "blodeuwedd", null, null, null, true, false, false, ""), + Row(children: [ + Provider.of(context).summary == "" + ? Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ + CircularProgressIndicator(color: settings.theme.defaultButtonActiveColor), + Padding(padding: EdgeInsets.all(5.0), child: Text(AppLocalizations.of(context)!.blodeuweddProcessing)) + ]) + : Flexible(child: Text(Provider.of(context).summary)) + ])); + + var image = Padding( + padding: EdgeInsets.all(4.0), + child: ProfileImage( + imagePath: "assets/blodeuwedd.png", + diameter: 48.0, + border: settings.theme.portraitOnlineBorderColor, + badgeTextColor: Colors.red, + badgeColor: Colors.red, + )); + + return Container( + height: 300, // bespoke value courtesy of the [TextField] docs + child: Container( + alignment: Alignment.center, + child: Padding( + padding: EdgeInsets.all(10.0), + child: Padding( + padding: EdgeInsets.all(10.0), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [image, Flexible(child: bubble)], + ))))); + }); + }, + context: context); +} diff --git a/lib/widgets/messagerow.dart b/lib/widgets/messagerow.dart index 53c4c55f..03ecc7c9 100644 --- a/lib/widgets/messagerow.dart +++ b/lib/widgets/messagerow.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'package:cwtch/config.dart'; @@ -118,6 +119,31 @@ class MessageRowState extends State with SingleTickerProviderStateMi }, icon: Icon(CwtchIcons.view_replies, color: Provider.of(context).theme.dropShadowColor))); + var profile = Provider.of(context, listen: false); + var conversation = Provider.of(context, listen: false); + var message = Provider.of(context, listen: false); + + Widget wdgTranslateMessage = Platform.isAndroid + ? SizedBox.shrink() + : Visibility( + visible: Provider.of(context, listen: false).cwtch.IsBlodeuweddSupported() && + Provider.of(context).isExperimentEnabled(BlodeuweddExperiment) && + EnvironmentConfig.TEST_MODE || + Provider.of(context).hoveredIndex == Provider.of(context).messageID, + maintainSize: true, + maintainAnimation: true, + maintainState: true, + maintainInteractivity: false, + child: IconButton( + tooltip: AppLocalizations.of(context)!.blodeuweddTranslate, + splashRadius: Material.defaultSplashRadius / 2, + onPressed: () { + Provider.of(context, listen: false).translation = ""; + Provider.of(context, listen: false).cwtch.TranslateMessage(profile.onion, conversation.identifier, message.messageID, "French"); + modalShowTranslation(context, profile, settings); + }, + icon: Icon(Icons.translate, color: Provider.of(context).theme.dropShadowColor))); + Widget wdgSpacer = Flexible(flex: 1, child: SizedBox(width: Platform.isAndroid ? 20 : 60, height: 10)); var widgetRow = []; @@ -125,6 +151,7 @@ class MessageRowState extends State with SingleTickerProviderStateMi widgetRow = [ wdgSpacer, wdgSeeReplies, + wdgTranslateMessage, wdgReply, actualMessage, ]; @@ -172,8 +199,6 @@ class MessageRowState extends State with SingleTickerProviderStateMi }); })), ]))), - wdgReply, - wdgSeeReplies, wdgSpacer, ]; } else { @@ -213,6 +238,7 @@ class MessageRowState extends State with SingleTickerProviderStateMi actualMessage, wdgReply, wdgSeeReplies, + wdgTranslateMessage, wdgSpacer, ]; } @@ -463,6 +489,60 @@ void modalShowReplies( }); } +void modalShowTranslation(BuildContext context, ProfileInfoState profile, Settings settings) async { + showModalBottomSheet( + builder: ( + BuildContext bcontext, + ) { + return StatefulBuilder(builder: (BuildContext scontext, StateSetter setState /*You can rename this!*/) { + if (scontext.mounted) { + new Timer.periodic(Duration(seconds: 1), (Timer t) { + if (scontext.mounted) { + setState(() {}); + } + }); + } + + var bubble = StaticMessageBubble( + profile, + settings, + MessageMetadata(profile.onion, Provider.of(context).identifier, 1, DateTime.now(), "blodeuwedd", null, null, null, true, false, false, ""), + Row(children: [ + Provider.of(context).translation == "" + ? Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ + CircularProgressIndicator(color: settings.theme.defaultButtonActiveColor), + Padding(padding: EdgeInsets.all(5.0), child: Text(AppLocalizations.of(context)!.blodeuweddProcessing)) + ]) + : Flexible(child: SelectableText(Provider.of(context).translation)) + ])); + + var image = Padding( + padding: EdgeInsets.all(4.0), + child: ProfileImage( + imagePath: "assets/blodeuwedd.png", + diameter: 48.0, + border: settings.theme.portraitOnlineBorderColor, + badgeTextColor: Colors.red, + badgeColor: Colors.red, + )); + + return Container( + height: 300, // bespoke value courtesy of the [TextField] docs + child: Container( + alignment: Alignment.center, + child: Padding( + padding: EdgeInsets.all(10.0), + child: Padding( + padding: EdgeInsets.all(10.0), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [image, Flexible(child: bubble)], + ))))); + }); + }, + context: context); +} + // temporary until we do real picture selection String RandomProfileImage(String onion) { var choices = [