From 3eff5f2d87e30e35130e4dd4b8f91b5df5633ef7 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 29 Aug 2026 17:19:24 +0000 Subject: [PATCH] Revert "feat: remove the AI writing helper from the post composer" This reverts commit a5e2aae9603ec003158a5af0c669ec204fa5f07f (PR #3979), bringing the on-device AI writing assistant back to the post composer: - restores the WritingAssistant abstraction with its play (ML Kit GenAI / Gemini Nano) and fdroid (no-op) implementations, the mock, and the AiWritingHelp panel/button - restores the AI state, the precompute job and the lifecycle wiring in ShortNotePostViewModel and ShortNotePostScreen - restores the genai-proofreading, genai-prompt and genai-rewriting dependencies - restores the "Propose text improvements" setting end to end: the Compose Settings tile, automaticallyProposeAiImprovements in UiSettings / UiSettingsFlow, the ui.propose_ai_improvements DataStore key, and the ai_writing_* / ai_tone_* strings in every locale The one deviation from a straight revert: initWritingAssistant now takes a `Context` by its simple name instead of the inline fully-qualified name the original had, since the file already imports it. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01YRfjXrjHdJ435kQwyp2HnL --- amethyst/build.gradle.kts | 5 + .../service/ai/NoOpWritingAssistant.kt | 32 ++++ .../service/ai/WritingAssistantFactory.kt | 28 +++ .../amethyst/model/UiSettings.kt | 1 + .../amethyst/model/UiSettingsFlow.kt | 23 ++- .../model/preferences/UISharedPreferences.kt | 3 + .../service/ai/MockWritingAssistant.kt | 99 ++++++++++ .../amethyst/service/ai/WritingAssistant.kt | 61 +++++++ .../creators/aihelp/AiWritingHelpButton.kt | 54 ++++++ .../creators/aihelp/AiWritingHelpPanel.kt | 169 ++++++++++++++++++ .../loggedIn/home/ShortNotePostScreen.kt | 14 ++ .../loggedIn/home/ShortNotePostViewModel.kt | 106 +++++++++++ .../settings/ComposeSettingsScreen.kt | 7 + .../src/main/res/values-ar-rSA/strings.xml | 14 ++ .../src/main/res/values-bn-rBD/strings.xml | 14 ++ amethyst/src/main/res/values-cs/strings.xml | 14 ++ .../src/main/res/values-de-rDE/strings.xml | 14 ++ amethyst/src/main/res/values-de/strings.xml | 14 ++ .../src/main/res/values-el-rGR/strings.xml | 13 ++ .../src/main/res/values-eo-rUY/strings.xml | 14 ++ amethyst/src/main/res/values-eo/strings.xml | 14 ++ .../src/main/res/values-es-rES/strings.xml | 13 ++ .../src/main/res/values-es-rMX/strings.xml | 13 ++ .../src/main/res/values-es-rUS/strings.xml | 13 ++ amethyst/src/main/res/values-es/strings.xml | 14 ++ .../src/main/res/values-fa-rIR/strings.xml | 14 ++ amethyst/src/main/res/values-fa/strings.xml | 14 ++ .../src/main/res/values-fi-rFI/strings.xml | 13 ++ .../src/main/res/values-fr-rCA/strings.xml | 13 ++ .../src/main/res/values-fr-rFR/strings.xml | 14 ++ amethyst/src/main/res/values-fr/strings.xml | 14 ++ .../src/main/res/values-hi-rIN/strings.xml | 14 ++ .../src/main/res/values-hu-rHU/strings.xml | 14 ++ .../src/main/res/values-in-rID/strings.xml | 13 ++ amethyst/src/main/res/values-in/strings.xml | 14 ++ .../src/main/res/values-it-rIT/strings.xml | 13 ++ .../src/main/res/values-ja-rJP/strings.xml | 14 ++ amethyst/src/main/res/values-ja/strings.xml | 14 ++ .../src/main/res/values-ko-rKR/strings.xml | 13 ++ .../src/main/res/values-lv-rLV/strings.xml | 13 ++ .../src/main/res/values-nl-rBE/strings.xml | 14 ++ .../src/main/res/values-nl-rNL/strings.xml | 14 ++ amethyst/src/main/res/values-nl/strings.xml | 14 ++ .../src/main/res/values-pl-rPL/strings.xml | 14 ++ .../src/main/res/values-pt-rBR/strings.xml | 14 ++ .../src/main/res/values-pt-rPT/strings.xml | 13 ++ .../src/main/res/values-ru-rRU/strings.xml | 14 ++ .../src/main/res/values-ru-rUA/strings.xml | 14 ++ amethyst/src/main/res/values-ru/strings.xml | 14 ++ .../src/main/res/values-sl-rSI/strings.xml | 14 ++ .../src/main/res/values-sr-rSP/strings.xml | 13 ++ .../src/main/res/values-sv-rSE/strings.xml | 14 ++ amethyst/src/main/res/values-sw/strings.xml | 13 ++ .../src/main/res/values-ta-rIN/strings.xml | 13 ++ amethyst/src/main/res/values-ta/strings.xml | 14 ++ .../src/main/res/values-th-rTH/strings.xml | 13 ++ amethyst/src/main/res/values-th/strings.xml | 14 ++ .../src/main/res/values-tr-rTR/strings.xml | 13 ++ amethyst/src/main/res/values-tr/strings.xml | 14 ++ .../src/main/res/values-uk-rUA/strings.xml | 14 ++ amethyst/src/main/res/values-uk/strings.xml | 14 ++ .../src/main/res/values-uz-rUZ/strings.xml | 12 ++ .../src/main/res/values-vi-rVN/strings.xml | 13 ++ .../src/main/res/values-zh-rCN/strings.xml | 14 ++ .../src/main/res/values-zh-rHK/strings.xml | 13 ++ .../src/main/res/values-zh-rSG/strings.xml | 13 ++ .../src/main/res/values-zh-rTW/strings.xml | 13 ++ amethyst/src/main/res/values-zh/strings.xml | 14 ++ amethyst/src/main/res/values/strings.xml | 14 ++ .../service/ai/MLKitWritingAssistant.kt | 169 ++++++++++++++++++ .../service/ai/WritingAssistantFactory.kt | 27 +++ gradle/libs.versions.toml | 6 + 72 files changed, 1559 insertions(+), 7 deletions(-) create mode 100644 amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/ai/NoOpWritingAssistant.kt create mode 100644 amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/ai/WritingAssistantFactory.kt create mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/service/ai/MockWritingAssistant.kt create mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/service/ai/WritingAssistant.kt create mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/aihelp/AiWritingHelpButton.kt create mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/aihelp/AiWritingHelpPanel.kt create mode 100644 amethyst/src/play/java/com/vitorpamplona/amethyst/service/ai/MLKitWritingAssistant.kt create mode 100644 amethyst/src/play/java/com/vitorpamplona/amethyst/service/ai/WritingAssistantFactory.kt diff --git a/amethyst/build.gradle.kts b/amethyst/build.gradle.kts index 2190d8bbb3..29d5e686d9 100644 --- a/amethyst/build.gradle.kts +++ b/amethyst/build.gradle.kts @@ -531,6 +531,11 @@ dependencies { // Google services model the translate text "playImplementation"(libs.google.mlkit.translate) + // On-device AI writing assistance (Gemini Nano via AICore) + "playImplementation"(libs.google.mlkit.genai.proofreading) + "playImplementation"(libs.google.mlkit.genai.prompt) + "playImplementation"(libs.google.mlkit.genai.rewriting) + // On-device alt-text suggestions: genai image description (preferred, descriptive sentences) // with image-labeling as a keyword-join fallback for devices without AICore. "playImplementation"(libs.google.mlkit.genai.image.description) diff --git a/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/ai/NoOpWritingAssistant.kt b/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/ai/NoOpWritingAssistant.kt new file mode 100644 index 0000000000..665cce0c39 --- /dev/null +++ b/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/ai/NoOpWritingAssistant.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.service.ai + +class NoOpWritingAssistant : WritingAssistant { + override suspend fun checkAvailability(): WritingAssistantStatus = WritingAssistantStatus.Unavailable + + override suspend fun transform( + text: String, + tone: WritingTone, + ): WritingResult = WritingResult(text, text, tone) + + override fun close() {} +} diff --git a/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/ai/WritingAssistantFactory.kt b/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/ai/WritingAssistantFactory.kt new file mode 100644 index 0000000000..bc5e51758f --- /dev/null +++ b/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/service/ai/WritingAssistantFactory.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.service.ai + +import android.content.Context + +object WritingAssistantFactory { + @Suppress("UNUSED_PARAMETER") + fun create(context: Context): WritingAssistant = NoOpWritingAssistant() +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettings.kt index cf0ffd0480..c3b9d7a1ed 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettings.kt @@ -39,6 +39,7 @@ data class UiSettings( val dontAskForNotificationPermissions: Boolean = false, val featureSet: FeatureSetType = FeatureSetType.SIMPLIFIED, val gallerySet: ProfileGalleryType = ProfileGalleryType.CLASSIC, + val automaticallyProposeAiImprovements: BooleanType = BooleanType.ALWAYS, val useTrackedBroadcasts: BooleanType = BooleanType.ALWAYS, val automaticallyCreateDrafts: BooleanType = BooleanType.ALWAYS, val showHomeNewThreadsTab: Boolean = true, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettingsFlow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettingsFlow.kt index 58c659b212..8faab9450d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettingsFlow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/UiSettingsFlow.kt @@ -39,6 +39,7 @@ class UiSettingsFlow( val dontAskForNotificationPermissions: MutableStateFlow = MutableStateFlow(false), val featureSet: MutableStateFlow = MutableStateFlow(FeatureSetType.SIMPLIFIED), val gallerySet: MutableStateFlow = MutableStateFlow(ProfileGalleryType.CLASSIC), + val automaticallyProposeAiImprovements: MutableStateFlow = MutableStateFlow(BooleanType.ALWAYS), val useTrackedBroadcasts: MutableStateFlow = MutableStateFlow(BooleanType.ALWAYS), val automaticallyCreateDrafts: MutableStateFlow = MutableStateFlow(BooleanType.ALWAYS), val showHomeNewThreadsTab: MutableStateFlow = MutableStateFlow(true), @@ -70,6 +71,7 @@ class UiSettingsFlow( dontAskForNotificationPermissions, featureSet, gallerySet, + automaticallyProposeAiImprovements, useTrackedBroadcasts, automaticallyCreateDrafts, showHomeNewThreadsTab, @@ -107,7 +109,7 @@ class UiSettingsFlow( flows[11] as ProfileGalleryType, flows[12] as BooleanType, flows[13] as BooleanType, - flows[14] as Boolean, + flows[14] as BooleanType, flows[15] as Boolean, flows[16] as Boolean, flows[17] as Boolean, @@ -115,12 +117,13 @@ class UiSettingsFlow( flows[19] as Boolean, flows[20] as Boolean, flows[21] as Boolean, - flows[22] as BooleanType, - flows[23] as AccentColorType, - flows[24] as FontFamilyType, - flows[25] as FontSizeType, - flows[26] as String, - flows[27] as Boolean, + flows[22] as Boolean, + flows[23] as BooleanType, + flows[24] as AccentColorType, + flows[25] as FontFamilyType, + flows[26] as FontSizeType, + flows[27] as String, + flows[28] as Boolean, ) } @@ -138,6 +141,7 @@ class UiSettingsFlow( dontAskForNotificationPermissions.value, featureSet.value, gallerySet.value, + automaticallyProposeAiImprovements.value, useTrackedBroadcasts.value, automaticallyCreateDrafts.value, showHomeNewThreadsTab.value, @@ -207,6 +211,10 @@ class UiSettingsFlow( gallerySet.tryEmit(torSettings.gallerySet) any = true } + if (automaticallyProposeAiImprovements.value != torSettings.automaticallyProposeAiImprovements) { + automaticallyProposeAiImprovements.tryEmit(torSettings.automaticallyProposeAiImprovements) + any = true + } if (useTrackedBroadcasts.value != torSettings.useTrackedBroadcasts) { useTrackedBroadcasts.tryEmit(torSettings.useTrackedBroadcasts) any = true @@ -308,6 +316,7 @@ class UiSettingsFlow( MutableStateFlow(uiSettings.dontAskForNotificationPermissions), MutableStateFlow(uiSettings.featureSet), MutableStateFlow(uiSettings.gallerySet), + MutableStateFlow(uiSettings.automaticallyProposeAiImprovements), MutableStateFlow(uiSettings.useTrackedBroadcasts), MutableStateFlow(uiSettings.automaticallyCreateDrafts), MutableStateFlow(uiSettings.showHomeNewThreadsTab), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/UISharedPreferences.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/UISharedPreferences.kt index cb421cc4ae..01f955a8c9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/UISharedPreferences.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/preferences/UISharedPreferences.kt @@ -130,6 +130,7 @@ class UiSharedPreferences( val UI_DONT_ASK_FOR_NOTIFICATION_PERMISSIONS = booleanPreferencesKey("ui.dont_ask_for_notification_permissions") val UI_FEATURE_SET = stringPreferencesKey("ui.feature_set") val UI_GALLERY_SET = stringPreferencesKey("ui.gallery_set") + val UI_PROPOSE_AI_IMPROVEMENTS = stringPreferencesKey("ui.propose_ai_improvements") val UI_USE_TRACKED_BROADCASTS = stringPreferencesKey("ui.use_tracked_broadcasts") val UI_AUTOMATICALLY_CREATE_DRAFTS = stringPreferencesKey("ui.automatically_create_drafts") val UI_SHOW_HOME_NEW_THREADS_TAB = booleanPreferencesKey("ui.show_home_new_threads_tab") @@ -167,6 +168,7 @@ class UiSharedPreferences( dontAskForNotificationPermissions = preferences[UI_DONT_ASK_FOR_NOTIFICATION_PERMISSIONS] ?: false, featureSet = featureSet, gallerySet = preferences[UI_GALLERY_SET]?.let { ProfileGalleryType.valueOf(it) } ?: ProfileGalleryType.CLASSIC, + automaticallyProposeAiImprovements = preferences[UI_PROPOSE_AI_IMPROVEMENTS]?.let { BooleanType.valueOf(it) } ?: BooleanType.ALWAYS, useTrackedBroadcasts = preferences[UI_USE_TRACKED_BROADCASTS]?.let { BooleanType.valueOf(it) } ?: if (featureSet == FeatureSetType.COMPLETE) BooleanType.ALWAYS else BooleanType.NEVER, @@ -222,6 +224,7 @@ class UiSharedPreferences( preferences[UI_DONT_ASK_FOR_NOTIFICATION_PERMISSIONS] = sharedSettings.dontAskForNotificationPermissions preferences[UI_FEATURE_SET] = sharedSettings.featureSet.name preferences[UI_GALLERY_SET] = sharedSettings.gallerySet.name + preferences[UI_PROPOSE_AI_IMPROVEMENTS] = sharedSettings.automaticallyProposeAiImprovements.name preferences[UI_USE_TRACKED_BROADCASTS] = sharedSettings.useTrackedBroadcasts.name preferences[UI_AUTOMATICALLY_CREATE_DRAFTS] = sharedSettings.automaticallyCreateDrafts.name preferences[UI_SHOW_HOME_NEW_THREADS_TAB] = sharedSettings.showHomeNewThreadsTab diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ai/MockWritingAssistant.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ai/MockWritingAssistant.kt new file mode 100644 index 0000000000..80b547a09d --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ai/MockWritingAssistant.kt @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.service.ai + +import kotlinx.coroutines.delay + +/** + * TODO: Remove before shipping. Debug-only mock for testing the AI writing help UI + * on devices without Gemini Nano / AICore support. + */ +class MockWritingAssistant : WritingAssistant { + override suspend fun checkAvailability(): WritingAssistantStatus = WritingAssistantStatus.Available + + override suspend fun transform( + text: String, + tone: WritingTone, + ): WritingResult { + delay(800) + + val transformed = + when (tone) { + WritingTone.CORRECT -> { + correctMock(text) + } + + WritingTone.REPHRASE -> { + "Here's another way to put it: $text" + } + + WritingTone.SHORTER -> { + text + .split(".") + .firstOrNull() + ?.trim() + ?.plus(".") ?: text + } + + WritingTone.ELABORATE -> { + "$text Furthermore, this point deserves deeper consideration and nuance." + } + + WritingTone.FRIENDLY -> { + "Hey! $text Hope that makes sense! :)" + } + + WritingTone.PROFESSIONAL -> { + "I would like to bring to your attention the following: $text" + } + + WritingTone.MORE_DIRECT -> { + text.replace("I think ", "").replace("maybe ", "").replace("perhaps ", "") + } + + WritingTone.PUNCHY -> { + text.uppercase().replace(".", "!") + } + + WritingTone.EMOJIFY -> { + "$text \uD83D\uDE80\uD83D\uDD25\u2728" + } + } + + return WritingResult( + originalText = text, + transformedText = transformed, + tone = tone, + ) + } + + private fun correctMock(text: String): String = + text + .replace("teh ", "the ") + .replace("dont ", "don't ") + .replace("cant ", "can't ") + .replace("wont ", "won't ") + .replace("i ", "I ") + + override fun close() { + // no-op: mock holds no native handles or background workers to release. + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ai/WritingAssistant.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ai/WritingAssistant.kt new file mode 100644 index 0000000000..e136ecba12 --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/ai/WritingAssistant.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.service.ai + +import androidx.compose.runtime.Immutable + +interface WritingAssistant { + suspend fun checkAvailability(): WritingAssistantStatus + + suspend fun transform( + text: String, + tone: WritingTone, + ): WritingResult + + fun close() +} + +enum class WritingTone { + CORRECT, + REPHRASE, + SHORTER, + ELABORATE, + FRIENDLY, + PROFESSIONAL, + MORE_DIRECT, + PUNCHY, + EMOJIFY, +} + +sealed class WritingAssistantStatus { + data object Available : WritingAssistantStatus() + + data object Unavailable : WritingAssistantStatus() + + data object Downloading : WritingAssistantStatus() +} + +@Immutable +data class WritingResult( + val originalText: String, + val transformedText: String, + val tone: WritingTone, +) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/aihelp/AiWritingHelpButton.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/aihelp/AiWritingHelpButton.kt new file mode 100644 index 0000000000..c057423ec4 --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/aihelp/AiWritingHelpButton.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.note.creators.aihelp + +import androidx.compose.foundation.layout.height +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.icons.symbols.Icon +import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.ui.stringRes + +@Composable +fun AiWritingHelpButton( + isActive: Boolean, + onClick: () -> Unit, +) { + IconButton( + onClick = { onClick() }, + ) { + Icon( + symbol = MaterialSymbols.AutoAwesome, + contentDescription = stringRes(R.string.ai_writing_help), + modifier = Modifier.height(22.dp), + tint = + if (isActive) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.onBackground + }, + ) + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/aihelp/AiWritingHelpPanel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/aihelp/AiWritingHelpPanel.kt new file mode 100644 index 0000000000..7eb2e6cbbe --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/aihelp/AiWritingHelpPanel.kt @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.note.creators.aihelp + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandVertically +import androidx.compose.animation.shrinkVertically +import androidx.compose.foundation.background +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.FilterChip +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.service.ai.WritingResult +import com.vitorpamplona.amethyst.service.ai.WritingTone +import com.vitorpamplona.amethyst.ui.stringRes + +@Composable +fun AiWritingHelpPanel( + isVisible: Boolean, + readyResults: Map, + selectedResult: WritingResult?, + onToneSelected: (WritingTone) -> Unit, + onApply: () -> Unit, + onDismiss: () -> Unit, +) { + AnimatedVisibility( + visible = isVisible, + enter = expandVertically(), + exit = shrinkVertically(), + ) { + Column( + modifier = + Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp), + ) { + selectedResult?.let { + AiResultCard( + result = it, + onApply = onApply, + onDismiss = onDismiss, + ) + } + + ToneChipRow( + readyTones = readyResults.keys, + selectedTone = selectedResult?.tone, + onToneSelected = onToneSelected, + ) + } + } +} + +@Composable +private fun AiResultCard( + result: WritingResult, + onApply: () -> Unit, + onDismiss: () -> Unit, +) { + Column( + modifier = + Modifier + .fillMaxWidth() + .padding(vertical = 4.dp) + .clip(RoundedCornerShape(12.dp)) + .background(MaterialTheme.colorScheme.surfaceVariant) + .padding(12.dp), + ) { + Text( + text = result.transformedText, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = + Modifier + .fillMaxWidth() + .heightIn(max = 150.dp) + .verticalScroll(rememberScrollState()), + ) + + Row( + modifier = + Modifier + .fillMaxWidth() + .padding(top = 8.dp), + horizontalArrangement = Arrangement.End, + ) { + TextButton(onClick = onDismiss) { + Text(stringRes(R.string.ai_writing_dismiss)) + } + OutlinedButton(onClick = onApply) { + Text(stringRes(R.string.ai_writing_use_this)) + } + } + } +} + +@Composable +private fun ToneChipRow( + readyTones: Set, + selectedTone: WritingTone?, + onToneSelected: (WritingTone) -> Unit, +) { + val scrollState = rememberScrollState() + Row( + modifier = + Modifier + .horizontalScroll(scrollState) + .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(6.dp), + ) { + WritingTone.entries.forEach { tone -> + if (tone in readyTones) { + FilterChip( + selected = tone == selectedTone, + onClick = { onToneSelected(tone) }, + label = { Text(toneDisplayName(tone)) }, + ) + } + } + } +} + +@Composable +private fun toneDisplayName(tone: WritingTone): String = + when (tone) { + WritingTone.CORRECT -> stringRes(R.string.ai_tone_correct) + WritingTone.REPHRASE -> stringRes(R.string.ai_tone_rephrase) + WritingTone.SHORTER -> stringRes(R.string.ai_tone_shorter) + WritingTone.ELABORATE -> stringRes(R.string.ai_tone_elaborate) + WritingTone.FRIENDLY -> stringRes(R.string.ai_tone_friendly) + WritingTone.PROFESSIONAL -> stringRes(R.string.ai_tone_professional) + WritingTone.MORE_DIRECT -> stringRes(R.string.ai_tone_more_direct) + WritingTone.PUNCHY -> stringRes(R.string.ai_tone_punchy) + WritingTone.EMOJIFY -> stringRes(R.string.ai_tone_emojify) + } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt index d079b09ab9..ad83d88608 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt @@ -103,6 +103,7 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.ui.note.BaseUserPicture import com.vitorpamplona.amethyst.ui.note.NoteCompose +import com.vitorpamplona.amethyst.ui.note.creators.aihelp.AiWritingHelpPanel import com.vitorpamplona.amethyst.ui.note.creators.contentWarning.ContentSensitivityExplainer import com.vitorpamplona.amethyst.ui.note.creators.contentWarning.MarkAsSensitiveButton import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.WatchAndLoadMyEmojiList @@ -179,6 +180,10 @@ fun ShortNotePostScreen( val activity = context.getActivity() val scope = rememberCoroutineScope() + LaunchedEffect(Unit) { + postViewModel.initWritingAssistant(context) + } + LaunchedEffect(postViewModel, accountViewModel) { val baseReplyTo = baseReplyToId?.let { accountViewModel.getNoteIfExists(it) } val quote = quoteId?.let { accountViewModel.getNoteIfExists(it) } @@ -709,6 +714,15 @@ private fun NewPostScreenBody( ) } + AiWritingHelpPanel( + isVisible = postViewModel.showAiPanel, + readyResults = postViewModel.aiResults, + selectedResult = postViewModel.aiSelectedResult, + onToneSelected = postViewModel::selectAiResult, + onApply = postViewModel::applyAiResult, + onDismiss = postViewModel::dismissAiResult, + ) + val alwaysOnEnabled by accountViewModel.account.settings.alwaysOnNotificationService .collectAsStateWithLifecycle() var showAlwaysOnPrompt by remember { mutableStateOf(false) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt index 84445e0ea1..ef64d79cd6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt @@ -46,10 +46,17 @@ import com.vitorpamplona.amethyst.commons.ui.text.replaceCurrentWord import com.vitorpamplona.amethyst.commons.ui.text.setTextAndPlaceCursorAtBeginning import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.AddressableNote +import com.vitorpamplona.amethyst.model.BooleanType import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.accountsCache.AccountCacheState +import com.vitorpamplona.amethyst.service.ai.MockWritingAssistant +import com.vitorpamplona.amethyst.service.ai.WritingAssistant +import com.vitorpamplona.amethyst.service.ai.WritingAssistantFactory +import com.vitorpamplona.amethyst.service.ai.WritingAssistantStatus +import com.vitorpamplona.amethyst.service.ai.WritingResult +import com.vitorpamplona.amethyst.service.ai.WritingTone import com.vitorpamplona.amethyst.service.location.LocationState import com.vitorpamplona.amethyst.service.uploads.CompressorQuality import com.vitorpamplona.amethyst.service.uploads.MediaCompressor @@ -158,7 +165,13 @@ import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.RandomInstance import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.ImmutableList +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch @@ -410,6 +423,96 @@ open class ShortNotePostViewModel : return accountViewModel.account.powDifficultyFor(anticipatedPowKind()) } + // AI Writing Help for testing + private val useMockAi = false + + var aiResults by mutableStateOf>(emptyMap()) + var aiSelectedResult by mutableStateOf(null) + var aiStatus by mutableStateOf(WritingAssistantStatus.Unavailable) + private var writingAssistant: WritingAssistant? = null + private var aiComputeJob: Job? = null + private var lastComputedText: String = "" + + val showAiPanel: Boolean + get() { + val prefEnabled = + accountViewModel.settings.uiSettingsFlow.automaticallyProposeAiImprovements.value == + BooleanType.ALWAYS + return prefEnabled && aiStatus is WritingAssistantStatus.Available && aiResults.isNotEmpty() + } + + fun initWritingAssistant(context: Context) { + if (writingAssistant == null) { + writingAssistant = + if (useMockAi) { + MockWritingAssistant() + } else { + WritingAssistantFactory.create(context) + } + viewModelScope.launch(Dispatchers.IO) { + aiStatus = writingAssistant?.checkAvailability() ?: WritingAssistantStatus.Unavailable + } + } + } + + fun precomputeAiResults() { + val assistant = writingAssistant ?: return + if (aiStatus !is WritingAssistantStatus.Available) return + val prefEnabled = + accountViewModel.settings.uiSettingsFlow.automaticallyProposeAiImprovements.value == + BooleanType.ALWAYS + if (!prefEnabled) return + + val text = message.text.toString().trim() + if (text.isBlank() || text == lastComputedText) return + + aiComputeJob?.cancel() + aiResults = emptyMap() + aiSelectedResult = null + + aiComputeJob = + viewModelScope.launch(Dispatchers.IO) { + delay(1000) + lastComputedText = text + + val results = + coroutineScope { + WritingTone.entries + .map { tone -> + async { + try { + assistant.transform(text, tone) + } catch (e: Exception) { + if (e is CancellationException) throw e + null + } + } + }.awaitAll() + .filterNotNull() + .associateBy { it.tone } + } + aiResults = results + } + } + + fun selectAiResult(tone: WritingTone) { + aiSelectedResult = aiResults[tone] + } + + fun applyAiResult() { + aiSelectedResult?.let { + message.setTextAndPlaceCursorAtEnd(it.transformedText) + aiSelectedResult = null + aiResults = emptyMap() + lastComputedText = "" + draftTag.newVersion() + } + } + + fun dismissAiResult() { + aiSelectedResult = null + } + fun lnAddress(): String? = account.userProfile().lnAddress() fun hasLnAddress(): Boolean = account.userProfile().lnAddress() != null @@ -1527,6 +1630,7 @@ open class ShortNotePostViewModel : emojiSuggestions?.processCurrentWord(lastWord) } + precomputeAiResults() draftTag.newVersion() } @@ -1765,6 +1869,8 @@ open class ShortNotePostViewModel : override fun onCleared() { super.onCleared() + writingAssistant?.close() + writingAssistant = null Log.d("Init") { "OnCleared: ${this.javaClass.simpleName}" } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ComposeSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ComposeSettingsScreen.kt index 21aefc2754..c70b623f31 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ComposeSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ComposeSettingsScreen.kt @@ -102,6 +102,13 @@ fun ComposeSettingsContent( description = R.string.auto_create_drafts_setting_description, ) SettingsDivider() + BooleanSwitchTile( + flow = sharedPrefs.automaticallyProposeAiImprovements, + icon = MaterialSymbols.AutoAwesome, + title = R.string.ai_writing_setting_title, + description = R.string.ai_writing_setting_description, + ) + SettingsDivider() BooleanSwitchTile( flow = sharedPrefs.useTrackedBroadcasts, icon = MaterialSymbols.CellTower, diff --git a/amethyst/src/main/res/values-ar-rSA/strings.xml b/amethyst/src/main/res/values-ar-rSA/strings.xml index d5e16f37e3..7174501ad2 100644 --- a/amethyst/src/main/res/values-ar-rSA/strings.xml +++ b/amethyst/src/main/res/values-ar-rSA/strings.xml @@ -3034,6 +3034,9 @@ تمت إزالة %1$d أعضاء من الـ relay طلب الانضمام إلى relay طلب مغادرة relay + مساعدة الذكاء الاصطناعي في الكتابة + اقتراح تحسينات النص + يستخدم نموذج ذكاء اصطناعي على الجهاز لاقتراح تصحيحات نصية وتغييرات في النبرة. البث المتتبَّع استخدم المذيع المتتبَّع عند إرسال الأحداث. يعرض تقدمًا مباشرًا وحالة كل relay أثناء البث. اقتراح تمارين للمشاركة @@ -3041,6 +3044,17 @@ إعدادات الكتابة إنشاء مسودات تلقائياً يحفظ حدثاً كمسودة تلقائياً عند الكتابة أو مغادرة محرر النص بنص غير مُرسل، ويرسله إلى relay صناديق الصادر الخاصة. + استخدام هذا + رفض + تصحيح + إعادة صياغة + أقصر + توسيع + ودّي + احترافي + أكثر مباشرة + قوي ومؤثر + + إيموجي حزم الإيموجي إضافة إلى قائمة الإيموجي diff --git a/amethyst/src/main/res/values-bn-rBD/strings.xml b/amethyst/src/main/res/values-bn-rBD/strings.xml index c627b2f29b..2c940681cd 100644 --- a/amethyst/src/main/res/values-bn-rBD/strings.xml +++ b/amethyst/src/main/res/values-bn-rBD/strings.xml @@ -2918,6 +2918,9 @@ Relay থেকে %1$d জন সদস্য সরানো হয়েছে Relay যোগ দেওয়ার অনুরোধ Relay ছেড়ে যাওয়ার অনুরোধ + AI লেখার সহায়তা + পাঠ্য উন্নতির প্রস্তাব দিন + পাঠ্য সংশোধন এবং সুরের পরিবর্তন প্রস্তাব করতে ডিভাইসে AI মডেল ব্যবহার করে। ট্র্যাকড সম্প্রচার ইভেন্ট পাঠানোর সময় ট্র্যাকড ব্রডকাস্টার ব্যবহার করুন। সম্প্রচার করার সময় লাইভ অগ্রগতি এবং প্রতি-relay অবস্থা দেখায়। শেয়ার করার জন্য ওয়ার্কআউট সুপারিশ করুন @@ -2925,6 +2928,17 @@ কম্পোজ সেটিংস স্বয়ংক্রিয়ভাবে খসড়া তৈরি করুন আপনি টাইপ করলে বা না-পাঠানো পাঠ্য সহ কম্পোজার ছেড়ে গেলে স্বয়ংক্রিয়ভাবে একটি খসড়া ইভেন্ট সংরক্ষণ করে এবং আপনার ব্যক্তিগত আউটবক্স relay-গুলোতে পাঠায়। + এটি ব্যবহার করুন + বাতিল করুন + সংশোধন + পুনরায় বলুন + সংক্ষিপ্ত + বিস্তারিত + বন্ধুত্বপূর্ণ + পেশাদার + আরো সরাসরি + প্রভাবশালী + + ইমোজি ইমোজি প্যাক ইমোজি তালিকায় যোগ করুন diff --git a/amethyst/src/main/res/values-cs/strings.xml b/amethyst/src/main/res/values-cs/strings.xml index 360d4d902e..c12cfe78d5 100644 --- a/amethyst/src/main/res/values-cs/strings.xml +++ b/amethyst/src/main/res/values-cs/strings.xml @@ -4727,6 +4727,9 @@ %1$d členů odebráno z relé Žádost o připojení k relé Žádost o opuštění relé + Asistent psaní s AI + Navrhovat vylepšení textu + Používá AI model běžící v zařízení k navrhování oprav textu a změn tónu. Sledovaná vysílání Použít sledovaného vysílače při odesílání událostí. Zobrazuje živý průběh a stav jednotlivých relayů během vysílání. Navrhovat tréninky ke sdílení @@ -4839,6 +4842,17 @@ Váš %1$s dokončil těžbu, ale nepodařilo se jej publikovat. Bude to zkuseno znovu při příštím spuštění aplikace. Chatová zpráva Nahlášení + Použít toto + Zavřít + Opravit + Přeformulovat + Kratší + Rozvést + Přátelský + Profesionální + Přímější + Úderný + + Emoji Emoji balíčky Přidat do seznamu emoji diff --git a/amethyst/src/main/res/values-de-rDE/strings.xml b/amethyst/src/main/res/values-de-rDE/strings.xml index b4a46ab044..6a0490ef3d 100644 --- a/amethyst/src/main/res/values-de-rDE/strings.xml +++ b/amethyst/src/main/res/values-de-rDE/strings.xml @@ -4539,6 +4539,9 @@ %1$d Mitglieder aus Relay entfernt Relay-Beitrittsanfrage Relay-Austrittsanfrage + KI-Schreibhilfe + Textverbesserungen vorschlagen + Verwendet ein KI-Modell auf dem Gerät, um Textkorrekturen und Tonänderungen vorzuschlagen. Verfolgte Übertragungen Verwende den verfolgten Broadcaster beim Senden von Ereignissen. Zeigt Live-Fortschritt und Status pro Relay während der Übertragung. Workouts zum Teilen vorschlagen @@ -4633,6 +4636,17 @@ Dein %1$s wurde fertig geschürft, konnte aber nicht veröffentlicht werden. Es wird beim nächsten Start der App erneut versucht. Chat-Nachricht Meldung + Verwenden + Schließen + Korrigieren + Umformulieren + Kürzer + Ausführen + Freundlich + Professionell + Direkter + Prägnant + + Emoji Emoji-Pakete Zur Emoji-Liste hinzufügen diff --git a/amethyst/src/main/res/values-de/strings.xml b/amethyst/src/main/res/values-de/strings.xml index ce9ac0db7b..60bb237774 100644 --- a/amethyst/src/main/res/values-de/strings.xml +++ b/amethyst/src/main/res/values-de/strings.xml @@ -4600,8 +4600,11 @@ anz der Bedingungen ist erforderlich Relay-Austrittsanfrage +KI-Schreibhilfe +Textverbesserungen vorschlagen +Verwendet ein KI-Modell auf dem Gerät, um Textkorrekturen und Tonänderungen vorzuschlagen. Verfolgte Übertragungen @@ -4617,16 +4620,27 @@ anz der Bedingungen ist erforderlich Speichert automatisch ein Entwurfsereignis, wenn du tippst oder den Editor mit ungesendetem Text verlässt, und sendet es an deine privaten ausgehenden Relays. +Verwenden +Schließen +Korrigieren +Umformulieren +Kürzer +Ausführen +Freundlich +Professionell +Direkter +Prägnant ++ Emoji Emoji-Pakete diff --git a/amethyst/src/main/res/values-el-rGR/strings.xml b/amethyst/src/main/res/values-el-rGR/strings.xml index d86bf240cf..f48825ce25 100644 --- a/amethyst/src/main/res/values-el-rGR/strings.xml +++ b/amethyst/src/main/res/values-el-rGR/strings.xml @@ -2862,6 +2862,9 @@ %1$d μέλη αφαιρέθηκαν από το relay Αίτηση συμμετοχής σε relay Αίτηση αποχώρησης από relay + Βοήθεια Συγγραφής AI + Πρόταση βελτιώσεων κειμένου + Χρησιμοποιεί ένα τοπικό μοντέλο AI για να προτείνει διορθώσεις κειμένου και αλλαγές τόνου. Παρακολουθούμενες μεταδόσεις Χρήση του παρακολουθούμενου αναμεταδότη κατά την αποστολή συμβάντων. Εμφανίζει ζωντανή πρόοδο και κατάσταση ανά relay κατά τη μετάδοση. Πρόταση προπονήσεων για κοινοποίηση @@ -2869,6 +2872,16 @@ Ρυθμίσεις Σύνταξης Αυτόματη δημιουργία προχείρων Αποθηκεύει αυτόματα ένα προχείρο συμβάν όταν πληκτρολογείτε ή εγκαταλείπετε ένα παράθυρο σύνταξης με μη αποσταλμένο κείμενο και το αποστέλλει στα ιδιωτικά outbox relay σας. + Χρήση Αυτού + Απόρριψη + Διόρθωση + Αναδιατύπωση + Συντομότερο + Επεξεργασία + Φιλικό + Επαγγελματικό + Πιο Άμεσο + Δυναμικό Πακέτα Emoji Προσθήκη στη Λίστα Emoji diff --git a/amethyst/src/main/res/values-eo-rUY/strings.xml b/amethyst/src/main/res/values-eo-rUY/strings.xml index f08c9961e5..4d6f729c1c 100644 --- a/amethyst/src/main/res/values-eo-rUY/strings.xml +++ b/amethyst/src/main/res/values-eo-rUY/strings.xml @@ -2921,6 +2921,9 @@ %1$d membroj forigitaj el relay Peto pri aliĝo al relay Peto pri foriro el relay + Helpo pri AI-Skribado + Proponi tekstajn plibonigojn + Uzas aparatan AI-modelon por proponi tekstajn korektojn kaj tondoŝanĝojn. Spurataj dissendoj Uzu la spuratan dissendanton kiam vi sendas eventojn. Montras vivan progreson kaj relay-specifan staton dum dissendado. Sugesti trejnadojn por dividi @@ -2928,6 +2931,17 @@ Agordoj de Verkado Aŭtomate krei skizojn Konservas skizon aŭtomate kiam vi tajpas aŭ forlasas verkiston kun nesendita teksto kaj sendas al viaj privataj eligaj relay-oj. + Uzi Ĉi Tion + Ignori + Korekti + Reformuligi + Pli Mallonga + Plidetali + Amika + Profesia + Pli Rekta + Trafa + + Emodžio Emodžio-Pakaj Aldoni al Emodžio-Listo diff --git a/amethyst/src/main/res/values-eo/strings.xml b/amethyst/src/main/res/values-eo/strings.xml index f362b871f3..315049f82f 100644 --- a/amethyst/src/main/res/values-eo/strings.xml +++ b/amethyst/src/main/res/values-eo/strings.xml @@ -2727,6 +2727,9 @@ %1$d membroj forigitaj el relay Peto pri aliĝo al relay Peto pri foriro el relay +Helpo pri AI-Skribado +Proponi tekstajn plibonigojn +Uzas aparatan AI-modelon por proponi tekstajn korektojn kaj tondoŝanĝojn. Spurataj dissendoj Uzu la spuratan dissendanton kiam vi sendas eventojn. Montras vivan progreson kaj relay-specifan staton dum dissendado. Sugesti trejnadojn por dividi @@ -2734,6 +2737,17 @@ Agordoj de Verkado Aŭtomate krei skizojn Konservas skizon aŭtomate kiam vi tajpas aŭ forlasas verkiston kun nesendita teksto kaj sendas al viaj privataj eligaj relay-oj. +Uzi Ĉi Tion +Ignori +Korekti +Reformuligi +Pli Mallonga +Plidetali +Amika +Profesia +Pli Rekta +Trafa ++ Emodžio Emodžio-Pakaj Aldoni al Emodžio-Listo Aldoni al mia emodžio-listo diff --git a/amethyst/src/main/res/values-es-rES/strings.xml b/amethyst/src/main/res/values-es-rES/strings.xml index b6152c15df..e168f49f2b 100644 --- a/amethyst/src/main/res/values-es-rES/strings.xml +++ b/amethyst/src/main/res/values-es-rES/strings.xml @@ -2982,6 +2982,9 @@ %1$d miembros eliminados del relay Solicitud de unión al relay Solicitud de salida del relay + Ayuda de escritura IA + Proponer mejoras de texto + Usa un modelo de IA en el dispositivo para proponer correcciones de texto y cambios de tono. Difusiones rastreadas Usa el emisor rastreado al enviar eventos. Muestra el progreso en tiempo real y el estado por relay durante la difusión. Sugerir entrenamientos para compartir @@ -2989,6 +2992,16 @@ Ajustes de composición Crear borradores automáticamente Guarda un borrador automáticamente cuando escribes o abandonas el compositor con texto no enviado, y lo envía a tus relays de bandeja de salida privada. + Usar esto + Descartar + Corregir + Reformular + Más corto + Ampliar + Amigable + Profesional + Más directo + Contundente Paquetes de emojis Añadir a la lista de emojis diff --git a/amethyst/src/main/res/values-es-rMX/strings.xml b/amethyst/src/main/res/values-es-rMX/strings.xml index 6edbb51793..f7fd2fd15b 100644 --- a/amethyst/src/main/res/values-es-rMX/strings.xml +++ b/amethyst/src/main/res/values-es-rMX/strings.xml @@ -2973,6 +2973,9 @@ %1$d miembros eliminados del relay Solicitud de unión al relay Solicitud de salida del relay + Ayuda de escritura IA + Proponer mejoras de texto + Usa un modelo de IA en el dispositivo para proponer correcciones de texto y cambios de tono. Difusiones rastreadas Usa el emisor rastreado al enviar eventos. Muestra el progreso en tiempo real y el estado por relay durante la difusión. Sugerir entrenamientos para compartir @@ -2980,6 +2983,16 @@ Ajustes de composición Crear borradores automáticamente Guarda un borrador automáticamente cuando escribes o abandonas el compositor con texto no enviado, y lo envía a tus relays de bandeja de salida privada. + Usar esto + Descartar + Corregir + Reformular + Más corto + Ampliar + Amigable + Profesional + Más directo + Contundente Paquetes de emojis Añadir a la lista de emojis diff --git a/amethyst/src/main/res/values-es-rUS/strings.xml b/amethyst/src/main/res/values-es-rUS/strings.xml index 108bc4ba72..4edf47141b 100644 --- a/amethyst/src/main/res/values-es-rUS/strings.xml +++ b/amethyst/src/main/res/values-es-rUS/strings.xml @@ -2973,6 +2973,9 @@ %1$d miembros eliminados del relay Solicitud de unión al relay Solicitud de salida del relay + Ayuda de escritura IA + Proponer mejoras de texto + Usa un modelo de IA en el dispositivo para proponer correcciones de texto y cambios de tono. Difusiones rastreadas Usa el emisor rastreado al enviar eventos. Muestra el progreso en tiempo real y el estado por relay durante la difusión. Sugerir entrenamientos para compartir @@ -2980,6 +2983,16 @@ Ajustes de composición Crear borradores automáticamente Guarda un borrador automáticamente cuando escribes o abandonas el compositor con texto no enviado, y lo envía a tus relays de bandeja de salida privada. + Usar esto + Descartar + Corregir + Reformular + Más corto + Ampliar + Amigable + Profesional + Más directo + Contundente Paquetes de emojis Añadir a la lista de emojis diff --git a/amethyst/src/main/res/values-es/strings.xml b/amethyst/src/main/res/values-es/strings.xml index 5ce832c9a2..d102234c04 100644 --- a/amethyst/src/main/res/values-es/strings.xml +++ b/amethyst/src/main/res/values-es/strings.xml @@ -3027,8 +3027,11 @@ Solicitud de salida del relay +Ayuda de escritura IA +Proponer mejoras de texto +Usa un modelo de IA en el dispositivo para proponer correcciones de texto y cambios de tono. Difusiones rastreadas @@ -3044,16 +3047,27 @@ Guarda un borrador automáticamente cuando escribes o abandonas el compositor con texto no enviado, y lo envía a tus relays de bandeja de salida privada. +Usar esto +Descartar +Corregir +Reformular +Más corto +Ampliar +Amigable +Profesional +Más directo +Contundente ++ Emoji Paquetes de emojis diff --git a/amethyst/src/main/res/values-fa-rIR/strings.xml b/amethyst/src/main/res/values-fa-rIR/strings.xml index d8eb91f2bb..9cc2126893 100644 --- a/amethyst/src/main/res/values-fa-rIR/strings.xml +++ b/amethyst/src/main/res/values-fa-rIR/strings.xml @@ -2933,6 +2933,9 @@ %1$d عضو از relay حذف شد درخواست پیوستن به relay درخواست خروج از relay + کمک نوشتاری هوش مصنوعی + پیشنهاد بهبود متن + از یک مدل هوش مصنوعی روی دستگاه برای پیشنهاد اصلاحات متن و تغییر لحن استفاده می‌کند. پخش‌های ردیابی‌شده هنگام ارسال رویدادها از پخش‌کننده ردیابی‌شده استفاده کنید. پیشرفت زنده و وضعیت هر relay را در حین پخش نشان می‌دهد. پیشنهاد اشتراک‌گذاری تمرینات @@ -2940,6 +2943,17 @@ تنظیمات نوشتن ایجاد خودکار پیش‌نویس هنگام تایپ یا خروج از یک ناحیه نوشتن با متن ارسال‌نشده، به‌طور خودکار یک رویداد پیش‌نویس ذخیره می‌کند و آن را به relay‌های صندوق خروجی خصوصی شما ارسال می‌کند. + استفاده از این + رد کردن + تصحیح + بازنویسی + کوتاه‌تر + بسط دادن + دوستانه + حرفه‌ای + مستقیم‌تر + تأثیرگذار + + ایموجی بسته‌های ایموجی افزودن به فهرست ایموجی diff --git a/amethyst/src/main/res/values-fa/strings.xml b/amethyst/src/main/res/values-fa/strings.xml index f37aa160a6..8e561836df 100644 --- a/amethyst/src/main/res/values-fa/strings.xml +++ b/amethyst/src/main/res/values-fa/strings.xml @@ -3678,8 +3678,11 @@ درخواست خروج از relay + کمک نوشتاری هوش مصنوعی + پیشنهاد بهبود متن + از یک مدل هوش مصنوعی روی دستگاه برای پیشنهاد اصلاحات متن و تغییر لحن استفاده می‌کند. پخش‌های ردیابی‌شده @@ -3695,16 +3698,27 @@ هنگام تایپ یا خروج از یک ناحیه نوشتن با متن ارسال‌نشده، به‌طور خودکار یک رویداد پیش‌نویس ذخیره می‌کند و آن را به relay‌های صندوق خروجی خصوصی شما ارسال می‌کند. + استفاده از این + رد کردن + تصحیح + بازنویسی + کوتاه‌تر + بسط دادن + دوستانه + حرفه‌ای + مستقیم‌تر + تأثیرگذار + + ایموجی بسته‌های ایموجی diff --git a/amethyst/src/main/res/values-fi-rFI/strings.xml b/amethyst/src/main/res/values-fi-rFI/strings.xml index 513e59c992..20b526c286 100644 --- a/amethyst/src/main/res/values-fi-rFI/strings.xml +++ b/amethyst/src/main/res/values-fi-rFI/strings.xml @@ -2893,6 +2893,9 @@ %1$d jäsentä poistettu relaylta Relayn liittymispyyntö Relayn poistumispyyntö + Tekoälyn kirjoitusapu + Ehdota tekstiparannuksia + Käyttää laitteen tekoälymallia ehdottamaan tekstikorjauksia ja sävymuutoksia. Seuratut lähetykset Käytä seurattua lähetintä tapahtumien lähettämiseen. Näyttää reaaliaikaiset edistymistiedot ja relay-kohtaisen tilan lähetyksen aikana. Ehdota treenejä jaettavaksi @@ -2900,6 +2903,16 @@ Kirjoitusasetukset Luo luonnokset automaattisesti Tallentaa luonnoksen automaattisesti, kun kirjoitat tai poistut kirjoitusnäkymästä lähettämättömällä tekstillä, ja lähettää sen yksityisiin lähteviin relayihisi. + Käytä tätä + Hylkää + Korjaa + Muotoile uudelleen + Lyhyempi + Laajenna + Ystävällinen + Ammattimainen + Suorempi + Napakka Emoji-paketit Lisää emoji-listaan diff --git a/amethyst/src/main/res/values-fr-rCA/strings.xml b/amethyst/src/main/res/values-fr-rCA/strings.xml index 685a4ebb64..6822f7a05b 100644 --- a/amethyst/src/main/res/values-fr-rCA/strings.xml +++ b/amethyst/src/main/res/values-fr-rCA/strings.xml @@ -2817,6 +2817,9 @@ %1$d membres retirés du relais Demande d\'adhésion au relais Demande de départ du relais + Aide à la rédaction IA + Proposer des améliorations de texte + Utilise un modèle IA embarqué pour proposer des corrections de texte et des changements de ton. Diffusions suivies Utilise le diffuseur suivi lors de l\'envoi d\'événements. Affiche la progression en direct et l\'état par relais pendant la diffusion. Suggérer des entraînements à partager @@ -2824,6 +2827,16 @@ Paramètres de composition Créer automatiquement des brouillons Enregistre automatiquement un brouillon lorsque vous tapez ou quittez un compositeur avec du texte non envoyé, et l\'envoie à vos relais de boîte d\'envoi privée. + Utiliser ceci + Ignorer + Corriger + Reformuler + Plus court + Développer + Amical + Professionnel + Plus direct + Percutant Packs d\'emojis Ajouter à la liste d\'emojis diff --git a/amethyst/src/main/res/values-fr-rFR/strings.xml b/amethyst/src/main/res/values-fr-rFR/strings.xml index 607d4be323..95db5c7e47 100644 --- a/amethyst/src/main/res/values-fr-rFR/strings.xml +++ b/amethyst/src/main/res/values-fr-rFR/strings.xml @@ -3190,6 +3190,9 @@ %1$d membres retirés du relais Demande d\'adhésion au relais Demande de départ du relais + Aide à la rédaction IA + Proposer des améliorations de texte + Utilise un modèle IA embarqué pour proposer des corrections de texte et des changements de ton. Diffusions suivies Utilise le diffuseur suivi lors de l\'envoi d\'événements. Affiche la progression en direct et l\'état par relais pendant la diffusion. Suggérer des entraînements à partager @@ -3210,6 +3213,17 @@ à tout moment maintenant Votre %1$s a fini de miner mais n\'a pas pu être publié : %2$s Signaler + Utiliser ceci + Ignorer + Corriger + Reformuler + Plus court + Développer + Amical + Professionnel + Plus direct + Percutant + + Émoji Packs d\'emojis Ajouter à la liste d\'emojis diff --git a/amethyst/src/main/res/values-fr/strings.xml b/amethyst/src/main/res/values-fr/strings.xml index 9c280c2f4b..946905be82 100644 --- a/amethyst/src/main/res/values-fr/strings.xml +++ b/amethyst/src/main/res/values-fr/strings.xml @@ -5004,8 +5004,11 @@ Demande de départ du relais +Aide à la rédaction IA +Proposer des améliorations de texte +Utilise un modèle IA embarqué pour proposer des corrections de texte et des changements de ton. Diffusions suivies @@ -5021,16 +5024,27 @@ Enregistre automatiquement un brouillon lorsque vous tapez ou quittez un compositeur avec du texte non envoyé, et l\'envoie à vos relais de boîte d\'envoi privée. +Utiliser ceci +Ignorer +Corriger +Reformuler +Plus court +Développer +Amical +Professionnel +Plus direct +Percutant ++ Emoji Packs d\'emojis diff --git a/amethyst/src/main/res/values-hi-rIN/strings.xml b/amethyst/src/main/res/values-hi-rIN/strings.xml index 3ea5c0db1d..9ad85fd584 100644 --- a/amethyst/src/main/res/values-hi-rIN/strings.xml +++ b/amethyst/src/main/res/values-hi-rIN/strings.xml @@ -4540,6 +4540,9 @@ %1$d सदस्य हटाए गए पुनःप्रसारक से पुनःप्रसारक से जुडने का अनुरोध पुनःप्रसारक से चले जाने का अनुरोध + एआई॰ लेखन सहायता + लेख शोधन प्रस्ताव करें + यन्त्र स्थित एआई॰ प्रतिरूप का प्रयोग करता है लेख सुधार तथा स्वर परिवर्तन प्रस्तावों के लिए। पदचिह्न युक्त प्रसारण पदचिह्न युक्त प्रसारक का उपयोग करें घटनाओं को भेजते समय। वर्तमान प्रगति दिखाता है तथा प्रत्येक पुनःप्रसारक की स्थिति प्रसारण करते समय। व्यायामों का सुझाव बाँटनें के लिए @@ -4634,6 +4637,17 @@ आपका %1$s खनन समाप्त हुआ पर प्रकाशित नहीं हो सका। अगली बार क्रमक आरम्भ होने पर इसका पुनःप्रयास किया जाएगा। चर्चा सन्देश वृत्तान्त + इसका प्रयोग करें + हटाएँ + सम्यक + वाक्याम्श पुनः लिखें + सूक्ष्मतर + विस्तार + मित्रतापूर्ण + व्यावसायिक + अधिक सीधा + आघाती + भावचिह्न युक्त भावचिह्न पोटलियाँ भावचिह्न सूची में जोडें diff --git a/amethyst/src/main/res/values-hu-rHU/strings.xml b/amethyst/src/main/res/values-hu-rHU/strings.xml index 587d851430..e3a678ff85 100644 --- a/amethyst/src/main/res/values-hu-rHU/strings.xml +++ b/amethyst/src/main/res/values-hu-rHU/strings.xml @@ -4541,6 +4541,9 @@ %1$d tag el lett távolítva az átjátszóról Átjátszóhoz való csatlakozás kérése Átjátszó elhagyásának kérése + Súgó az LLM-alapú íráshoz + Javaslatok a szöveg javítására + Az eszközön futó LLM-modell segítségével szövegjavításokkal és hangnemváltoztatásokkal kapcsolatos javaslatokat kaphat. Nyomon követhető közvetítések Nyomon követhető közvetítők használata az események küldesékor. Közvetítés közben megjeleníti a jelenlegi előrehaladást és az egyes átjátszók állapotát. Megosztandó edzések javaslása @@ -4635,6 +4638,17 @@ A(z) %1$s bányászata befejeződött, de nem sikerült közzétenni. A következő indításkor az alkalmazás újra megpróbálja. Csevegési üzenet Jelentés + Ennek használata + Eltüntetés + Javítás + Újrafogalmazás + Rövidebb + Kidolgozott + Barátságos + Szakmai + Közvetlenebb + Erőteljes + + Emodzsi Emodzsicsomagok Hozzáadás az emodzsilistához diff --git a/amethyst/src/main/res/values-in-rID/strings.xml b/amethyst/src/main/res/values-in-rID/strings.xml index 0c55483d81..cd26add1c4 100644 --- a/amethyst/src/main/res/values-in-rID/strings.xml +++ b/amethyst/src/main/res/values-in-rID/strings.xml @@ -2822,6 +2822,9 @@ Seharusnya %3$s %1$d anggota dihapus dari relay Permintaan bergabung relay Permintaan keluar relay + Bantuan Penulisan AI + Usulkan perbaikan teks + Menggunakan model AI di perangkat untuk mengusulkan koreksi teks dan perubahan nada. Siaran terlacak Gunakan penyiar terlacak saat mengirim acara. Menampilkan progres langsung dan status per-relay saat menyiarkan. Sarankan latihan untuk dibagikan @@ -2829,6 +2832,16 @@ Seharusnya %3$s Pengaturan Compose Buat draf secara otomatis Menyimpan acara draf secara otomatis saat Anda mengetik atau meninggalkan composer dengan teks yang belum dikirim dan mengirimnya ke relay outbox privat Anda. + Gunakan Ini + Tutup + Koreksi + Ungkapkan Ulang + Lebih Singkat + Elaborasi + Ramah + Profesional + Lebih Langsung + Tegas Paket Emoji Tambah ke Daftar Emoji diff --git a/amethyst/src/main/res/values-in/strings.xml b/amethyst/src/main/res/values-in/strings.xml index b204a6314c..4bbeea3481 100644 --- a/amethyst/src/main/res/values-in/strings.xml +++ b/amethyst/src/main/res/values-in/strings.xml @@ -4004,8 +4004,11 @@ Permintaan keluar relay + Bantuan Penulisan AI + Usulkan perbaikan teks + Menggunakan model AI di perangkat untuk mengusulkan koreksi teks dan perubahan nada. Siaran terlacak @@ -4021,16 +4024,27 @@ Menyimpan acara draf secara otomatis saat Anda mengetik atau meninggalkan composer dengan teks yang belum dikirim dan mengirimnya ke relay outbox privat Anda. + Gunakan Ini + Tutup + Koreksi + Ungkapkan Ulang + Lebih Singkat + Elaborasi + Ramah + Profesional + Lebih Langsung + Tegas + + Emoji Paket Emoji diff --git a/amethyst/src/main/res/values-it-rIT/strings.xml b/amethyst/src/main/res/values-it-rIT/strings.xml index 51756cdadf..4ef733f402 100644 --- a/amethyst/src/main/res/values-it-rIT/strings.xml +++ b/amethyst/src/main/res/values-it-rIT/strings.xml @@ -2859,6 +2859,9 @@ %1$d membri rimossi dal relay Richiesta di iscrizione al relay Richiesta di uscita dal relay + Assistenza Scrittura AI + Proponi miglioramenti al testo + Utilizza un modello AI sul dispositivo per proporre correzioni al testo e modifiche al tono. Trasmissioni tracciate Usa il trasmettitore tracciato per l\'invio degli eventi. Mostra l\'avanzamento in tempo reale e lo stato per ogni relay durante la trasmissione. Suggerisci allenamenti da condividere @@ -2866,6 +2869,16 @@ Impostazioni Composizione Crea bozze automaticamente Salva automaticamente una bozza dell\'evento quando scrivi o esci da un compositore con testo non inviato, e la invia ai tuoi relay di outbox privati. + Usa Questo + Ignora + Correggi + Riformula + Più breve + Approfondisci + Amichevole + Professionale + Più diretto + Incisivo Pacchetti Emoji Aggiungi alla Lista Emoji diff --git a/amethyst/src/main/res/values-ja-rJP/strings.xml b/amethyst/src/main/res/values-ja-rJP/strings.xml index 13bc7ab0c0..9ce13f0cc5 100644 --- a/amethyst/src/main/res/values-ja-rJP/strings.xml +++ b/amethyst/src/main/res/values-ja-rJP/strings.xml @@ -2877,6 +2877,9 @@ %1$d 人のメンバーが relay から削除されました Relay 参加リクエスト Relay 退出リクエスト + AI ライティングサポート + テキストの改善を提案 + デバイス上のAIモデルを使用して、テキストの修正やトーンの変更を提案します。 追跡ブロードキャスト イベントの送信時に追跡ブロードキャスターを使用します。ブロードキャスト中にライブの進捗とrelay別のステータスを表示します。 ワークアウトの共有を提案する @@ -2884,6 +2887,17 @@ 作成の設定 自動的に下書きを作成する 入力中または未送信のテキストがある状態でコンポーザーを離れると、下書きイベントを自動的に保存し、プライベートのアウトボックスrelayに送信します。 + これを使用する + 閉じる + 修正する + 言い換える + 短くする + 詳しく書く + フレンドリーに + プロフェッショナルに + より直接的に + パンチを効かせる + + 絵文字 絵文字パック 絵文字リストに追加 diff --git a/amethyst/src/main/res/values-ja/strings.xml b/amethyst/src/main/res/values-ja/strings.xml index e35d5e93d1..10a6297efb 100644 --- a/amethyst/src/main/res/values-ja/strings.xml +++ b/amethyst/src/main/res/values-ja/strings.xml @@ -4093,8 +4093,11 @@ Relay 退出リクエスト + AI ライティングサポート + テキストの改善を提案 + デバイス上のAIモデルを使用して、テキストの修正やトーンの変更を提案します。 追跡ブロードキャスト @@ -4110,16 +4113,27 @@ 入力中または未送信のテキストがある状態でコンポーザーを離れると、下書きイベントを自動的に保存し、プライベートのアウトボックスrelayに送信します。 + これを使用する + 閉じる + 修正する + 言い換える + 短くする + 詳しく書く + フレンドリーに + プロフェッショナルに + より直接的に + パンチを効かせる + + 絵文字 絵文字パック diff --git a/amethyst/src/main/res/values-ko-rKR/strings.xml b/amethyst/src/main/res/values-ko-rKR/strings.xml index 08b37d46ca..6fa704a11e 100644 --- a/amethyst/src/main/res/values-ko-rKR/strings.xml +++ b/amethyst/src/main/res/values-ko-rKR/strings.xml @@ -2864,6 +2864,9 @@ Relay에서 %1$d명의 멤버가 제거되었습니다 Relay 가입 요청 Relay 탈퇴 요청 + AI 작성 도우미 + 텍스트 개선 제안 + 기기 내 AI 모델을 사용하여 텍스트 수정 및 톤 변경을 제안합니다. 추적된 방송 이벤트를 전송할 때 추적 브로드캐스터를 사용합니다. 방송하는 동안 실시간 진행 상황 및 relay별 상태를 표시합니다. 운동 공유 제안 @@ -2871,6 +2874,16 @@ 작성 설정 자동으로 임시 저장 텍스트를 입력하거나 전송하지 않은 텍스트가 있는 작성 화면을 떠날 때 자동으로 임시 저장 이벤트를 저장하고 개인 outbox relay로 전송합니다. + 이것 사용 + 닫기 + 교정 + 다시 표현 + 더 짧게 + 자세히 + 친근하게 + 전문적으로 + 더 직접적으로 + 임팩트 있게 Emoji 팩 Emoji 목록에 추가 diff --git a/amethyst/src/main/res/values-lv-rLV/strings.xml b/amethyst/src/main/res/values-lv-rLV/strings.xml index afcb18393a..93d6921901 100644 --- a/amethyst/src/main/res/values-lv-rLV/strings.xml +++ b/amethyst/src/main/res/values-lv-rLV/strings.xml @@ -2947,6 +2947,9 @@ %1$d dalībnieki noņemti no relay servera Relay pievienošanās pieprasījums Relay aiziešanas pieprasījums + MI rakstīšanas palīdzība + Piedāvāt teksta uzlabojumus + Izmanto ierīcē esošu MI modeli, lai piedāvātu teksta labojumus un toņa izmaiņas. Izsekotās pārraides Izmantot izsekoto raidītāju, sūtot notikumus. Parāda tiešraides progresu un katra relay statusa informāciju pārraides laikā. Ieteikt kopīgojamas treniņu sesijas @@ -2954,6 +2957,16 @@ Rakstīšanas iestatījumi Automātiski izveidot melnrakstus Automātiski saglabā melnrakstu, kad rakstāt vai atstājat redaktoru ar nesūtītu tekstu, un nosūta uz jūsu privātajiem izejas relay serveriem. + Izmantot šo + Noraidīt + Labot + Pārfrāzēt + Īsāk + Izvērst + Draudzīgi + Profesionāli + Tiešāk + Izteiksmīgi Emoji pakotnes Pievienot emoji sarakstam diff --git a/amethyst/src/main/res/values-nl-rBE/strings.xml b/amethyst/src/main/res/values-nl-rBE/strings.xml index 7b89e99a69..3b54759cd7 100644 --- a/amethyst/src/main/res/values-nl-rBE/strings.xml +++ b/amethyst/src/main/res/values-nl-rBE/strings.xml @@ -5057,8 +5057,11 @@ Relay-opzegverzoek +AI-schrijfassistent +Tekstverbeteringen voorstellen +Gebruikt een on-device AI-model om tekstcorrecties en toonwijzigingen voor te stellen. Getrackte uitzendingen @@ -5074,16 +5077,27 @@ Slaat automatisch een concept op wanneer je typt of de opsteller verlaat met onverzonden tekst en stuurt dit naar je privé outbox-relays. +Gebruik dit +Sluiten +Corrigeren +Herschrijven +Korter +Uitbreiden +Vriendelijk +Professioneel +Directer +Kort en krachtig ++ Emoji Emoji-pakketten diff --git a/amethyst/src/main/res/values-nl-rNL/strings.xml b/amethyst/src/main/res/values-nl-rNL/strings.xml index 50ced68fa2..a88334ff5f 100644 --- a/amethyst/src/main/res/values-nl-rNL/strings.xml +++ b/amethyst/src/main/res/values-nl-rNL/strings.xml @@ -4502,6 +4502,9 @@ %1$d leden verwijderd van relay Relay-lidmaatschapsverzoek Relay-opzegverzoek + AI-schrijfassistent + Tekstverbeteringen voorstellen + Gebruikt een on-device AI-model om tekstcorrecties en toonwijzigingen voor te stellen. Getrackte uitzendingen Gebruik de tracked broadcaster bij het verzenden van events. Toont live voortgang en per-relay-status tijdens uitzenden. Workouts voorstellen om te delen @@ -4596,6 +4599,17 @@ Je %1$s is klaar met mijnen maar kon niet worden gepubliceerd. Het wordt opnieuw geprobeerd de volgende keer dat de app start. Chatbericht Melding + Gebruik dit + Sluiten + Corrigeren + Herschrijven + Korter + Uitbreiden + Vriendelijk + Professioneel + Directer + Kort en krachtig + + Emoji Emoji-pakketten Toevoegen aan emoji-lijst diff --git a/amethyst/src/main/res/values-nl/strings.xml b/amethyst/src/main/res/values-nl/strings.xml index fa84c4d57e..3acc7a7b50 100644 --- a/amethyst/src/main/res/values-nl/strings.xml +++ b/amethyst/src/main/res/values-nl/strings.xml @@ -4350,8 +4350,11 @@ Relay-opzegverzoek +AI-schrijfassistent +Tekstverbeteringen voorstellen +Gebruikt een on-device AI-model om tekstcorrecties en toonwijzigingen voor te stellen. Getrackte uitzendingen @@ -4367,16 +4370,27 @@ Slaat automatisch een concept op wanneer je typt of de opsteller verlaat met onverzonden tekst en stuurt dit naar je privé outbox-relays. +Gebruik dit +Sluiten +Corrigeren +Herschrijven +Korter +Uitbreiden +Vriendelijk +Professioneel +Directer +Kort en krachtig ++ Emoji Emoji-pakketten diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 252eb0ccb1..7386e0565e 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -4729,6 +4729,9 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest %1$d użytkowników usuniętych z transmitera Prośba o dołączenie do transmitera Żądanie opuszczenia transmitera + Pomoc w pisaniu z użyciem AI + Zaproponuj poprawki w tekście + Używa modelu sztucznej inteligencji wbudowanego w urządzenie, proponując poprawki tekstu i zmiany tonu wypowiedzi. Monitorowane transmisje Podczas wysyłania zdarzeń korzystaj z monitora transmisji. Pokazuje postęp na żywo i status transmisji podczas nadawania. Zaproponuj treningi, którymi warto się podzielić @@ -4841,6 +4844,17 @@ Zaplanowane posty z innych kont nie zostaną opublikowane, dopóki to konto jest Twój %1$s zakończył wydobywanie, ale nie udało się go opublikować. Próba zostanie powtórzona przy następnym uruchomieniu aplikacji. Wiadomość Czatu Zgłoś + Użyj tego + Ignoruj + Popraw + Przeformułuj + Krócej + Rozwiń + Przyjazny + Profesjonalny + Bardziej bezpośredni + Mocny + + Emoji Pakiety emotikonów Dodaj do listy emotikonów diff --git a/amethyst/src/main/res/values-pt-rBR/strings.xml b/amethyst/src/main/res/values-pt-rBR/strings.xml index 0835563ef8..bb99198d89 100644 --- a/amethyst/src/main/res/values-pt-rBR/strings.xml +++ b/amethyst/src/main/res/values-pt-rBR/strings.xml @@ -4537,6 +4537,9 @@ %1$d membros removidos do relay Solicitação de entrada no relay Solicitação de saída do relay + Assistente de escrita com IA + Sugerir melhorias de texto + Usa um modelo de IA no dispositivo para sugerir correções de texto e mudanças de tom. Transmissões rastreadas Usar o transmissor rastreado ao enviar eventos. Mostra progresso ao vivo e status por relay durante a transmissão. Sugerir treinos para compartilhar @@ -4631,6 +4634,17 @@ Seu %1$s terminou de minerar, mas não pôde ser publicado. Uma nova tentativa será feita na próxima vez que o app iniciar. Mensagem de chat Denúncia + Usar isto + Dispensar + Corrigir + Reformular + Mais curto + Elaborar + Amigável + Profissional + Mais direto + Impactante + + Emoji Pacotes de emojis Adicionar à lista de emojis diff --git a/amethyst/src/main/res/values-pt-rPT/strings.xml b/amethyst/src/main/res/values-pt-rPT/strings.xml index d09eee4fba..5bf105abe2 100644 --- a/amethyst/src/main/res/values-pt-rPT/strings.xml +++ b/amethyst/src/main/res/values-pt-rPT/strings.xml @@ -2881,6 +2881,9 @@ %1$d membros removidos do relay Solicitação de entrada no relay Solicitação de saída do relay + Assistente de escrita com IA + Sugerir melhorias de texto + Usa um modelo de IA no dispositivo para sugerir correções de texto e mudanças de tom. Transmissões rastreadas Usar o transmissor rastreado ao enviar eventos. Mostra progresso ao vivo e status por relay durante a transmissão. Sugerir treinos para compartilhar @@ -2888,6 +2891,16 @@ Configurações de composição Criar rascunhos automaticamente Salva um evento de rascunho automaticamente quando você digita ou sai do compositor com texto não enviado e envia para seus relays de saída privados. + Usar isto + Dispensar + Corrigir + Reformular + Mais curto + Elaborar + Amigável + Profissional + Mais direto + Impactante Pacotes de emojis Adicionar à lista de emojis diff --git a/amethyst/src/main/res/values-ru-rRU/strings.xml b/amethyst/src/main/res/values-ru-rRU/strings.xml index 1d9a4e44b8..6b2ac98959 100644 --- a/amethyst/src/main/res/values-ru-rRU/strings.xml +++ b/amethyst/src/main/res/values-ru-rRU/strings.xml @@ -2955,6 +2955,9 @@ %1$d участников удалено из relay Запрос на вступление в relay Запрос на выход из relay + Помощь ИИ в написании + Предлагать улучшения текста + Использует модель ИИ на устройстве для предложения исправлений текста и изменения тональности. Отслеживаемые трансляции Использует отслеживаемый режим при отправке событий. Показывает прогресс в реальном времени и статус по каждому relay. Предлагать публикации тренировок @@ -2962,6 +2965,17 @@ Настройки редактора Автоматически создавать черновики Автоматически сохраняет черновик при вводе текста или выходе из редактора с неотправленным текстом и отправляет в ваши приватные outbox relay. + Использовать + Отклонить + Исправить + Перефразировать + Короче + Подробнее + Дружелюбно + Профессионально + Прямее + Энергично + + Эмодзи Наборы эмодзи Добавить в список эмодзи diff --git a/amethyst/src/main/res/values-ru-rUA/strings.xml b/amethyst/src/main/res/values-ru-rUA/strings.xml index b13cc9366d..5f31d82dbd 100644 --- a/amethyst/src/main/res/values-ru-rUA/strings.xml +++ b/amethyst/src/main/res/values-ru-rUA/strings.xml @@ -2938,6 +2938,9 @@ %1$d участников удалено из relay Запрос на вступление в relay Запрос на выход из relay + Помощь ИИ в написании + Предлагать улучшения текста + Использует модель ИИ на устройстве для предложения исправлений текста и изменения тональности. Отслеживаемые трансляции Использует отслеживаемый режим при отправке событий. Показывает прогресс в реальном времени и статус по каждому relay. Предлагать публикации тренировок @@ -2945,6 +2948,17 @@ Настройки редактора Автоматически создавать черновики Автоматически сохраняет черновик при вводе текста или выходе из редактора с неотправленным текстом и отправляет в ваши приватные outbox relay. + Использовать + Отклонить + Исправить + Перефразировать + Короче + Подробнее + Дружелюбно + Профессионально + Прямее + Энергично + + Эмодзи Наборы эмодзи Добавить в список эмодзи diff --git a/amethyst/src/main/res/values-ru/strings.xml b/amethyst/src/main/res/values-ru/strings.xml index f02ba4dad9..51a3e60b77 100644 --- a/amethyst/src/main/res/values-ru/strings.xml +++ b/amethyst/src/main/res/values-ru/strings.xml @@ -3846,8 +3846,11 @@ Запрос на выход из relay + Помощь ИИ в написании + Предлагать улучшения текста + Использует модель ИИ на устройстве для предложения исправлений текста и изменения тональности. Отслеживаемые трансляции @@ -3863,16 +3866,27 @@ Автоматически сохраняет черновик при вводе текста или выходе из редактора с неотправленным текстом и отправляет в ваши приватные outbox relay. + Использовать + Отклонить + Исправить + Перефразировать + Короче + Подробнее + Дружелюбно + Профессионально + Прямее + Энергично + + Эмодзи Наборы эмодзи diff --git a/amethyst/src/main/res/values-sl-rSI/strings.xml b/amethyst/src/main/res/values-sl-rSI/strings.xml index 5d6db172b3..c3fc28fae7 100644 --- a/amethyst/src/main/res/values-sl-rSI/strings.xml +++ b/amethyst/src/main/res/values-sl-rSI/strings.xml @@ -4727,6 +4727,9 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem %1$d članov odstranjenih iz releja Prošnja za dostop do releja Prošnja za izstop z releja + Pomoč za pisanje z umetno inteligenco + Predlagaj tekstovne izboljšave + Uporablja model umetne inteligence v napravi za predloge popravkov besedila in spremembe tona. Sledeni prenosi Pri pošiljanju dogodkov uporabi sledilnik oddajanja. V živo prikazuje napredek in stanje posameznih relejev med oddajanjem. Predlagaj vadbo za deljenje @@ -4839,6 +4842,17 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Vaš %1$s je končal z rudarjenjem, vendar ga ni bilo mogoče objaviti. Ponovni poskus bo izveden ob naslednjem zagonu aplikacije. Sporočilo klepeta Prijavi + Uporabi to + Prekliči + Pravilno + Izrazi drugače + Krajše + Razloži podrobneje + Prijateljsko + Profesionalno + Boj direktno + Udarno + + Emoji Emoji paketi Dodaj v seznam emojijev diff --git a/amethyst/src/main/res/values-sr-rSP/strings.xml b/amethyst/src/main/res/values-sr-rSP/strings.xml index e4117a350c..e9f1d480f1 100644 --- a/amethyst/src/main/res/values-sr-rSP/strings.xml +++ b/amethyst/src/main/res/values-sr-rSP/strings.xml @@ -2918,6 +2918,9 @@ %1$d članova uklonjeno iz relay-a Zahtev za pridruživanje relay-u Zahtev za napuštanje relay-a + Pomoć AI pri pisanju + Predloži poboljšanja teksta + Koristi AI model na uređaju za predlaganje ispravki teksta i promena tona. Praćena emitovanja Koristite praćeni emiter pri slanju događaja. Prikazuje uživo napredak i status po relay-u tokom emitovanja. Predloži treninge za deljenje @@ -2925,6 +2928,16 @@ Postavke pisanja Automatski kreiraj nacrte Automatski čuva nacrt kada kucate ili napustite editor sa neposlat im tekstom i šalje na vaše privatne odlazne relay-e. + Koristi ovo + Odbaci + Ispravi + Preformuliši + Kraće + Razradi + Prijateljski + Profesionalno + Direktnije + Upečatljivo Emoji paketi Dodaj na emoji listu diff --git a/amethyst/src/main/res/values-sv-rSE/strings.xml b/amethyst/src/main/res/values-sv-rSE/strings.xml index 314c6f5a31..f948ac3197 100644 --- a/amethyst/src/main/res/values-sv-rSE/strings.xml +++ b/amethyst/src/main/res/values-sv-rSE/strings.xml @@ -4537,6 +4537,9 @@ %1$d medlemmar borttagna från relä Begäran om att gå med i relä Begäran om att lämna relä + AI-skrivhjälp + Föreslå textförbättringar + Använder en AI-modell på enheten för att föreslå textkorrigeringar och tonändringar. Spårade sändningar Använd den spårade sändaren när du skickar händelser. Visar liveförlopp och status per relä under sändning. Föreslå träningspass att dela @@ -4631,6 +4634,17 @@ Ditt %1$s slutförde miningen men kunde inte publiceras. Det görs ett nytt försök nästa gång appen startar. Chattmeddelande Rapport + Använd detta + Avvisa + Korrigera + Formulera om + Kortare + Utveckla + Vänlig + Professionell + Mer direkt + Slagkraftig + + Emoji Emoji-paket Lägg till i emoji-lista diff --git a/amethyst/src/main/res/values-sw/strings.xml b/amethyst/src/main/res/values-sw/strings.xml index c77fb0aa69..df095d4322 100644 --- a/amethyst/src/main/res/values-sw/strings.xml +++ b/amethyst/src/main/res/values-sw/strings.xml @@ -2900,6 +2900,9 @@ %1$d wanachama wameondolewa kutoka relay Ombi la kujiunga na relay Ombi la kuacha relay + Msaada wa Uandishi wa AI + Pendekeza maboresho ya maandishi + Hutumia mfano wa AI uliopo kwenye kifaa kupendekeza marekebisho ya maandishi na mabadiliko ya sauti. Matangazo yanayofuatiliwa Tumia mtangazaji anayefuatiliwa wakati wa kutuma matukio. Inaonyesha maendeleo ya moja kwa moja na hali ya kila relay wakati wa kutangaza. Pendekeza mazoezi ya kushiriki @@ -2907,6 +2910,16 @@ Mipangilio ya Kutunga Unda rasimu kiotomatiki Huhifadhi tukio la rasimu kiotomatiki unapoandika au kuacha kitenzi cha kutunga chenye maandishi ambayo hayajatumwa na kutuma kwa relay zako za kibinafsi za outbox. + Tumia Hii + Ondoa + Sahihisha + Badilisha Maneno + Fupisho + Panua + Kirafiki + Kitaalamu + Zaidi ya Moja kwa Moja + Chenye Nguvu Pakiti za Emoji Ongeza kwenye Orodha ya Emoji diff --git a/amethyst/src/main/res/values-ta-rIN/strings.xml b/amethyst/src/main/res/values-ta-rIN/strings.xml index c2308aa7f0..805fbc7780 100644 --- a/amethyst/src/main/res/values-ta-rIN/strings.xml +++ b/amethyst/src/main/res/values-ta-rIN/strings.xml @@ -2888,6 +2888,9 @@ %1$d உறுப்பினர்கள் relay-லிருந்து நீக்கப்பட்டனர் Relay சேரும் கோரிக்கை Relay விலகும் கோரிக்கை + AI எழுத்து உதவி + உரை மேம்பாடுகளை பரிந்துரை செய்யவும் + உரை திருத்தங்கள் மற்றும் தொனி மாற்றங்களை பரிந்துரைக்க சாதனத்திலுள்ள AI மாதிரியை பயன்படுத்துகிறது. கண்காணிக்கப்பட்ட ஒளிபரப்புகள் நிகழ்வுகளை அனுப்பும்போது கண்காணிக்கப்பட்ட ஒளிபரப்பாளரை பயன்படுத்தவும். ஒளிபரப்பும்போது நேரடி முன்னேற்றம் மற்றும் ஒவ்வொரு relay நிலையையும் காட்டுகிறது. பகிர உடற்பயிற்சிகளை பரிந்துரை செய்யவும் @@ -2895,6 +2898,16 @@ எழுதும் அமைப்புகள் தானாக வரைவுகளை உருவாக்கவும் நீங்கள் தட்டச்சு செய்யும்போது அல்லது அனுப்பப்படாத உரையுடன் ஒரு எழுத்துக் கலைஞரை விட்டு வெளியேறும்போது தானாகவே வரைவு நிகழ்வை சேமித்து உங்கள் தனிப்பட்ட outbox relays-களுக்கு அனுப்புகிறது. + இதை பயன்படுத்து + நிராகரி + சரிசெய் + மீண்டும் வடிவமை + குறுகியது + விரிவாக்கு + நட்புடன் + தொழில்முறை + நேரடியாக + சுறுசுறுப்பான Emoji தொகுப்புகள் Emoji பட்டியலில் சேர் diff --git a/amethyst/src/main/res/values-ta/strings.xml b/amethyst/src/main/res/values-ta/strings.xml index 1776162374..1b0d9237b8 100644 --- a/amethyst/src/main/res/values-ta/strings.xml +++ b/amethyst/src/main/res/values-ta/strings.xml @@ -2727,6 +2727,9 @@ %1$d உறுப்பினர்கள் relay-லிருந்து நீக்கப்பட்டனர் Relay சேரும் கோரிக்கை Relay விலகும் கோரிக்கை +AI எழுத்து உதவி +உரை மேம்பாடுகளை பரிந்துரை செய்யவும் +உரை திருத்தங்கள் மற்றும் தொனி மாற்றங்களை பரிந்துரைக்க சாதனத்திலுள்ள AI மாதிரியை பயன்படுத்துகிறது. கண்காணிக்கப்பட்ட ஒளிபரப்புகள் நிகழ்வுகளை அனுப்பும்போது கண்காணிக்கப்பட்ட ஒளிபரப்பாளரை பயன்படுத்தவும். ஒளிபரப்பும்போது நேரடி முன்னேற்றம் மற்றும் ஒவ்வொரு relay நிலையையும் காட்டுகிறது. பகிர உடற்பயிற்சிகளை பரிந்துரை செய்யவும் @@ -2734,6 +2737,17 @@ எழுதும் அமைப்புகள் தானாக வரைவுகளை உருவாக்கவும் நீங்கள் தட்டச்சு செய்யும்போது அல்லது அனுப்பப்படாத உரையுடன் ஒரு எழுத்துக் கலைஞரை விட்டு வெளியேறும்போது தானாகவே வரைவு நிகழ்வை சேமித்து உங்கள் தனிப்பட்ட outbox relays-களுக்கு அனுப்புகிறது. +இதை பயன்படுத்து +நிராகரி +சரிசெய் +மீண்டும் வடிவமை +குறுகியது +விரிவாக்கு +நட்புடன் +தொழில்முறை +நேரடியாக +சுறுசுறுப்பான ++ Emoji Emoji தொகுப்புகள் Emoji பட்டியலில் சேர் என் emoji பட்டியலில் சேர் diff --git a/amethyst/src/main/res/values-th-rTH/strings.xml b/amethyst/src/main/res/values-th-rTH/strings.xml index d58dc64628..8c174b3e87 100644 --- a/amethyst/src/main/res/values-th-rTH/strings.xml +++ b/amethyst/src/main/res/values-th-rTH/strings.xml @@ -2725,6 +2725,9 @@ ลบ %1$d สมาชิกออกจาก relay แล้ว คำขอเข้าร่วม Relay คำขอออกจาก Relay + ความช่วยเหลือการเขียนด้วย AI + เสนอการปรับปรุงข้อความ + ใช้โมเดล AI บนอุปกรณ์เพื่อเสนอการแก้ไขข้อความและการเปลี่ยนแปลงโทนเสียง การออกอากาศที่ติดตาม ใช้ตัวออกอากาศที่ติดตามเมื่อส่งกิจกรรม แสดงความคืบหน้าสดและสถานะต่อ relay ขณะออกอากาศ แนะนำการออกกำลังกายเพื่อแชร์ @@ -2732,6 +2735,16 @@ การตั้งค่าการแต่ง สร้างร่างโดยอัตโนมัติ บันทึกกิจกรรมร่างโดยอัตโนมัติเมื่อคุณพิมพ์หรือออกจากตัวแต่งที่มีข้อความที่ยังไม่ได้ส่ง และส่งไปยัง relay outbox ส่วนตัวของคุณ + ใช้สิ่งนี้ + ปิด + แก้ไข + เรียบเรียงใหม่ + สั้นลง + ขยายความ + เป็นกันเอง + เป็นมืออาชีพ + ตรงไปตรงมามากขึ้น + กระชับ แพ็ค Emoji เพิ่มในรายการ Emoji diff --git a/amethyst/src/main/res/values-th/strings.xml b/amethyst/src/main/res/values-th/strings.xml index f1df3c2d32..b0df883049 100644 --- a/amethyst/src/main/res/values-th/strings.xml +++ b/amethyst/src/main/res/values-th/strings.xml @@ -3766,8 +3766,11 @@ คำขอออกจาก Relay + ความช่วยเหลือการเขียนด้วย AI + เสนอการปรับปรุงข้อความ + ใช้โมเดล AI บนอุปกรณ์เพื่อเสนอการแก้ไขข้อความและการเปลี่ยนแปลงโทนเสียง การออกอากาศที่ติดตาม @@ -3783,16 +3786,27 @@ บันทึกกิจกรรมร่างโดยอัตโนมัติเมื่อคุณพิมพ์หรือออกจากตัวแต่งที่มีข้อความที่ยังไม่ได้ส่ง และส่งไปยัง relay outbox ส่วนตัวของคุณ + ใช้สิ่งนี้ + ปิด + แก้ไข + เรียบเรียงใหม่ + สั้นลง + ขยายความ + เป็นกันเอง + เป็นมืออาชีพ + ตรงไปตรงมามากขึ้น + กระชับ + + Emoji แพ็ค Emoji diff --git a/amethyst/src/main/res/values-tr-rTR/strings.xml b/amethyst/src/main/res/values-tr-rTR/strings.xml index 7ec3fae6ec..91e2b80169 100644 --- a/amethyst/src/main/res/values-tr-rTR/strings.xml +++ b/amethyst/src/main/res/values-tr-rTR/strings.xml @@ -2901,6 +2901,9 @@ %1$d üye relay\'den kaldırıldı Relay katılım isteği Relay ayrılma isteği + Yapay Zeka Yazma Yardımı + Metin iyileştirmeleri öner + Metin düzeltmeleri ve ton değişiklikleri önermek için cihaz üzerindeki bir yapay zeka modeli kullanır. Takip edilen yayınlar Etkinlikler gönderilirken takip edilen yayıncıyı kullan. Yayın sırasında canlı ilerlemeyi ve relay başına durumu gösterir. Paylaşılacak antrenmanlar öner @@ -2908,6 +2911,16 @@ Oluşturma Ayarları Otomatik olarak taslak oluştur Yazarken veya gönderilmemiş metin içeren bir düzenleyiciden ayrılırken otomatik olarak taslak etkinliği kaydeder ve özel giden kutusu relay\'lerinize gönderir. + Bunu Kullan + Kapat + Düzelt + Yeniden İfade Et + Daha Kısa + Detaylandır + Samimi + Profesyonel + Daha Doğrudan + Etkili Emoji Paketleri Emoji Listesine Ekle diff --git a/amethyst/src/main/res/values-tr/strings.xml b/amethyst/src/main/res/values-tr/strings.xml index af90d8e320..1832869ce8 100644 --- a/amethyst/src/main/res/values-tr/strings.xml +++ b/amethyst/src/main/res/values-tr/strings.xml @@ -4282,8 +4282,11 @@ Relay ayrılma isteği + Yapay Zeka Yazma Yardımı + Metin iyileştirmeleri öner + Metin düzeltmeleri ve ton değişiklikleri önermek için cihaz üzerindeki bir yapay zeka modeli kullanır. Takip edilen yayınlar @@ -4299,16 +4302,27 @@ Yazarken veya gönderilmemiş metin içeren bir düzenleyiciden ayrılırken otomatik olarak taslak etkinliği kaydeder ve özel giden kutusu relay\'lerinize gönderir. + Bunu Kullan + Kapat + Düzelt + Yeniden İfade Et + Daha Kısa + Detaylandır + Samimi + Profesyonel + Daha Doğrudan + Etkili + + Emoji Emoji Paketleri diff --git a/amethyst/src/main/res/values-uk-rUA/strings.xml b/amethyst/src/main/res/values-uk-rUA/strings.xml index ebc5d152c6..8567db9af2 100644 --- a/amethyst/src/main/res/values-uk-rUA/strings.xml +++ b/amethyst/src/main/res/values-uk-rUA/strings.xml @@ -2944,6 +2944,9 @@ %1$d учасників видалено з relay Запит на вступ до relay Запит на вихід з relay + Допомога AI з написанням + Пропонувати вдосконалення тексту + Використовує AI-модель на пристрої для пропозиції виправлень тексту та зміни тону. Відстежувані трансляції Використовувати відстежувальний транслятор під час надсилання подій. Відображає живий прогрес та статус по кожному relay під час трансляції. Пропонувати тренування для поширення @@ -2951,6 +2954,17 @@ Налаштування редактора Автоматично створювати чернетки Автоматично зберігає чернетку події, коли ви друкуєте або залишаєте редактор з ненадісленим текстом, і надсилає до ваших приватних вихідних relay. + Використати + Відхилити + Виправити + Перефразувати + Коротше + Розгорнути + Дружній + Професійний + Більш прямий + Влучний + + Емодзі Пакети емодзі Додати до списку емодзі diff --git a/amethyst/src/main/res/values-uk/strings.xml b/amethyst/src/main/res/values-uk/strings.xml index 37de944186..60b747c20e 100644 --- a/amethyst/src/main/res/values-uk/strings.xml +++ b/amethyst/src/main/res/values-uk/strings.xml @@ -4091,8 +4091,11 @@ Запит на вихід з relay + Допомога AI з написанням + Пропонувати вдосконалення тексту + Використовує AI-модель на пристрої для пропозиції виправлень тексту та зміни тону. Відстежувані трансляції @@ -4108,16 +4111,27 @@ Автоматично зберігає чернетку події, коли ви друкуєте або залишаєте редактор з ненадісленим текстом, і надсилає до ваших приватних вихідних relay. + Використати + Відхилити + Виправити + Перефразувати + Коротше + Розгорнути + Дружній + Професійний + Більш прямий + Влучний + + Емодзі Пакети емодзі diff --git a/amethyst/src/main/res/values-uz-rUZ/strings.xml b/amethyst/src/main/res/values-uz-rUZ/strings.xml index 1501b099e6..04c05d0863 100644 --- a/amethyst/src/main/res/values-uz-rUZ/strings.xml +++ b/amethyst/src/main/res/values-uz-rUZ/strings.xml @@ -2905,6 +2905,9 @@ %1$d a\'zo relay dan chiqarildi Relay ga qo\'shilish so\'rovi Relay dan chiqish so\'rovi + AI yozish yordami + Matn yaxshilanishlarini taklif qilish + Matn tuzatishlar va ohang o\'zgarishlarini taklif qilish uchun qurilmadagi AI modelidan foydalanadi. Kuzatilgan translyatsiyalar Hodisalarni yuborishda kuzatilgan translyator dan foydalaning. Translyatsiya vaqtida jonli holat va har bir relay holati ko\'rsatiladi. Ulashish uchun mashg\'ulotlar taklif qilish @@ -2912,6 +2915,15 @@ Yozish sozlamalari Avtomatik qoralamalar yaratish Yozsangiz yoki yuborilmagan matn bilan kompositordan chiqib ketsangiz qoralama hodisasini avtomatik saqlaydi va shaxsiy chiqish relay laringizga yuboradi. + Buni ishlatish + Yopish + To\'g\'rilash + Qayta ifodalash + Qisqaroq + Batafsil + Do\'stona + To\'g\'riroq + Ifodali Emoji to\'plamlari Emoji ro\'yxatiga qo\'shish diff --git a/amethyst/src/main/res/values-vi-rVN/strings.xml b/amethyst/src/main/res/values-vi-rVN/strings.xml index 49f77a1136..4ee23deb1e 100644 --- a/amethyst/src/main/res/values-vi-rVN/strings.xml +++ b/amethyst/src/main/res/values-vi-rVN/strings.xml @@ -2846,6 +2846,9 @@ Đã xóa %1$d thành viên khỏi relay Yêu cầu tham gia relay Yêu cầu rời relay + Trợ lý AI viết văn + Đề xuất cải thiện văn bản + Sử dụng mô hình AI trên thiết bị để đề xuất sửa lỗi văn bản và thay đổi giọng điệu. Phát sóng có theo dõi Sử dụng trình phát sóng có theo dõi khi gửi sự kiện. Hiển thị tiến trình trực tiếp và trạng thái từng relay trong khi phát sóng. Đề xuất chia sẻ bài tập @@ -2853,6 +2856,16 @@ Cài đặt soạn thảo Tự động tạo bản nháp Tự động lưu sự kiện nháp khi bạn gõ hoặc rời khỏi trình soạn thảo có văn bản chưa gửi, và gửi đến các relay outbox riêng tư của bạn. + Dùng cái này + Đóng + Sửa lỗi + Diễn đạt lại + Ngắn hơn + Mở rộng + Thân thiện + Chuyên nghiệp + Trực tiếp hơn + Mạnh mẽ Gói Emoji Thêm vào danh sách Emoji diff --git a/amethyst/src/main/res/values-zh-rCN/strings.xml b/amethyst/src/main/res/values-zh-rCN/strings.xml index 55d70a8c0b..c947cac36b 100644 --- a/amethyst/src/main/res/values-zh-rCN/strings.xml +++ b/amethyst/src/main/res/values-zh-rCN/strings.xml @@ -3795,6 +3795,9 @@ 从中继删除了 %1$d 位成员 中继加入请求 中继离开请求 + AI 写入帮助 + 建议文本改进 + 使用设备上的 AI 模型来提出文本更正和音调更改。 已跟踪的广播 在发送事件时使用已跟踪的广播。在广播时显示实时进度和每个中继的状态。 推荐要分享的锻炼 @@ -3875,6 +3878,17 @@ 您的 %1$s 完成了挖掘,但无法发布。将在下次应用程序启动时重新尝试。 聊天消息 举报 + 使用它 + 忽略 + 更正 + 改写 + 较短 + 详述 + 友好 + 专业 + 更直接 + 强有力 + + Emoji 表情包 添加到表情列表 diff --git a/amethyst/src/main/res/values-zh-rHK/strings.xml b/amethyst/src/main/res/values-zh-rHK/strings.xml index 46f1b2fb74..a54d2dde9b 100644 --- a/amethyst/src/main/res/values-zh-rHK/strings.xml +++ b/amethyst/src/main/res/values-zh-rHK/strings.xml @@ -2914,6 +2914,9 @@ 从中继删除了 %1$d 位成员 中继加入请求 中继离开请求 + AI 写入帮助 + 建议文本改进 + 使用设备上的 AI 模型来提出文本更正和音调更改。 已跟踪的广播 在发送事件时使用已跟踪的广播。在广播时显示实时进度和每个中继的状态。 推荐要分享的锻炼 @@ -2921,6 +2924,16 @@ 撰写设置 自动创建草稿 当您输入或在编辑器中有未发送的文本时自动保存草稿事件并发送到您的私人发件箱中继。 + 使用它 + 忽略 + 更正 + 改写 + 较短 + 详述 + 友好 + 专业 + 更直接 + 强有力 表情包 添加到表情列表 diff --git a/amethyst/src/main/res/values-zh-rSG/strings.xml b/amethyst/src/main/res/values-zh-rSG/strings.xml index b5a106dd59..d7748d9119 100644 --- a/amethyst/src/main/res/values-zh-rSG/strings.xml +++ b/amethyst/src/main/res/values-zh-rSG/strings.xml @@ -2914,6 +2914,9 @@ 从中继删除了 %1$d 位成员 中继加入请求 中继离开请求 + AI 写入帮助 + 建议文本改进 + 使用设备上的 AI 模型来提出文本更正和音调更改。 已跟踪的广播 在发送事件时使用已跟踪的广播。在广播时显示实时进度和每个中继的状态。 推荐要分享的锻炼 @@ -2921,6 +2924,16 @@ 撰写设置 自动创建草稿 当您输入或在编辑器中有未发送的文本时自动保存草稿事件并发送到您的私人发件箱中继。 + 使用它 + 忽略 + 更正 + 改写 + 较短 + 详述 + 友好 + 专业 + 更直接 + 强有力 表情包 添加到表情列表 diff --git a/amethyst/src/main/res/values-zh-rTW/strings.xml b/amethyst/src/main/res/values-zh-rTW/strings.xml index c425469664..fedfaa3a7a 100644 --- a/amethyst/src/main/res/values-zh-rTW/strings.xml +++ b/amethyst/src/main/res/values-zh-rTW/strings.xml @@ -2880,6 +2880,9 @@ %1$d 位成員已從 relay 移除 Relay 加入申請 Relay 退出申請 + AI 寫作輔助 + 建議文字改進 + 使用裝置上的 AI 模型提出文字修正和語氣變更建議。 追蹤廣播 傳送事件時使用追蹤廣播器。廣播時顯示即時進度和每個 relay 的狀態。 建議分享運動紀錄 @@ -2887,6 +2890,16 @@ 撰寫設定 自動建立草稿 當您輸入或離開含有未送出文字的撰寫器時,自動儲存草稿事件並傳送至您的私人發件箱 relay。 + 使用此版本 + 關閉 + 修正 + 改寫 + 縮短 + 詳述 + 友善 + 專業 + 更直接 + 有力 Emoji 包 新增至 Emoji 清單 diff --git a/amethyst/src/main/res/values-zh/strings.xml b/amethyst/src/main/res/values-zh/strings.xml index 1e0c15e604..9b57f44fc9 100644 --- a/amethyst/src/main/res/values-zh/strings.xml +++ b/amethyst/src/main/res/values-zh/strings.xml @@ -5496,8 +5496,11 @@ 中继离开请求 +AI 写入帮助 +建议文本改进 +使用设备上的 AI 模型来提出文本更正和音调更改。 已跟踪的广播 @@ -5513,16 +5516,27 @@ 当您输入或在编辑器中有未发送的文本时自动保存草稿事件并发送到您的私人发件箱中继。 +使用它 +忽略 +更正 +改写 +较短 +详述 +友好 +专业 +更直接 +强有力 ++ Emoji 表情包 diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 6c6fc903e8..557eea9ba5 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -4918,6 +4918,9 @@ Relay join request Relay leave request + AI Writing Help + Propose text improvements + Uses an on-device AI model to propose text corrections and tone changes. Tracked broadcasts Use the tracked broadcaster when sending events. Shows live progress and per-relay status while broadcasting. Suggest workouts to share @@ -5012,6 +5015,17 @@ Your %1$s finished mining but could not be published. It will be retried the next time the app starts. Chat message Report + Use This + Dismiss + Correct + Rephrase + Shorter + Elaborate + Friendly + Professional + More Direct + Punchy + + Emoji Emoji Packs diff --git a/amethyst/src/play/java/com/vitorpamplona/amethyst/service/ai/MLKitWritingAssistant.kt b/amethyst/src/play/java/com/vitorpamplona/amethyst/service/ai/MLKitWritingAssistant.kt new file mode 100644 index 0000000000..fec0416252 --- /dev/null +++ b/amethyst/src/play/java/com/vitorpamplona/amethyst/service/ai/MLKitWritingAssistant.kt @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.service.ai + +import android.content.Context +import com.google.android.gms.tasks.Tasks +import com.google.mlkit.genai.common.FeatureStatus +import com.google.mlkit.genai.proofreading.Proofreader +import com.google.mlkit.genai.proofreading.ProofreaderOptions +import com.google.mlkit.genai.proofreading.Proofreading +import com.google.mlkit.genai.proofreading.ProofreadingRequest +import com.google.mlkit.genai.rewriting.Rewriter +import com.google.mlkit.genai.rewriting.RewriterOptions +import com.google.mlkit.genai.rewriting.Rewriting +import com.google.mlkit.genai.rewriting.RewritingRequest +import com.vitorpamplona.amethyst.service.lang.LanguageTranslatorService +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +class MLKitWritingAssistant( + private val context: Context, +) : WritingAssistant { + private var rewriters = mutableMapOf() + private var proofreaders = mutableMapOf() + + private fun rewriterCacheKey( + @RewriterOptions.OutputType outputType: Int, + @RewriterOptions.Language language: Int, + ): Long = (outputType.toLong() shl 32) or language.toLong() + + private fun getRewriter( + @RewriterOptions.OutputType outputType: Int, + @RewriterOptions.Language language: Int, + ): Rewriter = + rewriters.getOrPut(rewriterCacheKey(outputType, language)) { + Rewriting.getClient( + RewriterOptions + .builder(context) + .setOutputType(outputType) + .setLanguage(language) + .build(), + ) + } + + private fun getProofreader( + @ProofreaderOptions.Language language: Int, + ): Proofreader = + proofreaders.getOrPut(language) { + Proofreading.getClient( + ProofreaderOptions + .builder(context) + .setInputType(ProofreaderOptions.InputType.KEYBOARD) + .setLanguage(language) + .build(), + ) + } + + override suspend fun checkAvailability(): WritingAssistantStatus = + withContext(Dispatchers.IO) { + try { + val rewriter = getRewriter(RewriterOptions.OutputType.REPHRASE, RewriterOptions.Language.ENGLISH) + val status = rewriter.checkFeatureStatus().get() + when (status) { + FeatureStatus.AVAILABLE -> WritingAssistantStatus.Available + FeatureStatus.DOWNLOADING -> WritingAssistantStatus.Downloading + else -> WritingAssistantStatus.Unavailable + } + } catch (e: Exception) { + WritingAssistantStatus.Unavailable + } + } + + override suspend fun transform( + text: String, + tone: WritingTone, + ): WritingResult { + val language = detectLanguage(text) + val transformedText = + when (tone) { + WritingTone.CORRECT -> proofread(text, language) + WritingTone.REPHRASE -> rewrite(text, RewriterOptions.OutputType.REPHRASE, language) + WritingTone.SHORTER -> rewrite(text, RewriterOptions.OutputType.SHORTEN, language) + WritingTone.ELABORATE -> rewrite(text, RewriterOptions.OutputType.ELABORATE, language) + WritingTone.FRIENDLY -> rewrite(text, RewriterOptions.OutputType.FRIENDLY, language) + WritingTone.PROFESSIONAL -> rewrite(text, RewriterOptions.OutputType.PROFESSIONAL, language) + WritingTone.EMOJIFY -> rewrite(text, RewriterOptions.OutputType.EMOJIFY, language) + WritingTone.MORE_DIRECT -> rewrite(text, RewriterOptions.OutputType.PROFESSIONAL, language) + WritingTone.PUNCHY -> rewrite(text, RewriterOptions.OutputType.SHORTEN, language) + } + + return WritingResult( + originalText = text, + transformedText = transformedText, + tone = tone, + ) + } + + private suspend fun detectLanguage(text: String): Int = + withContext(Dispatchers.IO) { + try { + val langTag = Tasks.await(LanguageTranslatorService.identifyLanguage(text)) + mapLanguageTag(langTag) + } catch (e: Exception) { + RewriterOptions.Language.ENGLISH + } + } + + private suspend fun rewrite( + text: String, + @RewriterOptions.OutputType outputType: Int, + @RewriterOptions.Language language: Int, + ): String = + withContext(Dispatchers.IO) { + val rewriter = getRewriter(outputType, language) + val request = RewritingRequest.builder(text).build() + val result = rewriter.runInference(request).get() + result.results.firstOrNull()?.text ?: text + } + + private suspend fun proofread( + text: String, + @ProofreaderOptions.Language language: Int, + ): String = + withContext(Dispatchers.IO) { + val proofreader = getProofreader(language) + val request = ProofreadingRequest.builder(text).build() + val result = proofreader.runInference(request).get() + result.results.firstOrNull()?.text ?: text + } + + override fun close() { + rewriters.values.forEach { it.close() } + rewriters.clear() + proofreaders.values.forEach { it.close() } + proofreaders.clear() + } + + companion object { + fun mapLanguageTag(tag: String?): Int = + when (tag?.lowercase()?.take(2)) { + "en" -> RewriterOptions.Language.ENGLISH + "ja" -> RewriterOptions.Language.JAPANESE + "ko" -> RewriterOptions.Language.KOREAN + "de" -> RewriterOptions.Language.GERMAN + "fr" -> RewriterOptions.Language.FRENCH + "it" -> RewriterOptions.Language.ITALIAN + "es" -> RewriterOptions.Language.SPANISH + else -> RewriterOptions.Language.ENGLISH + } + } +} diff --git a/amethyst/src/play/java/com/vitorpamplona/amethyst/service/ai/WritingAssistantFactory.kt b/amethyst/src/play/java/com/vitorpamplona/amethyst/service/ai/WritingAssistantFactory.kt new file mode 100644 index 0000000000..86525c2d95 --- /dev/null +++ b/amethyst/src/play/java/com/vitorpamplona/amethyst/service/ai/WritingAssistantFactory.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.service.ai + +import android.content.Context + +object WritingAssistantFactory { + fun create(context: Context): WritingAssistant = MLKitWritingAssistant(context) +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 281c4cb327..f19b09c9ca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,6 +40,9 @@ kotlin = "2.4.10" kotlinxCollectionsImmutable = "0.5.1" kotlinxCoroutinesCore = "1.11.0" kotlinxSerialization = "1.11.0" +genaiProofreading = "1.0.0-beta1" +genaiPrompt = "1.0.0-beta4" +genaiRewriting = "1.0.0-beta1" genaiImageDescription = "1.0.0-beta1" languageId = "17.0.6" lifecycleRuntimeKtx = "2.11.0" @@ -177,6 +180,9 @@ jetbrains-compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = " jetbrains-compose-ui-tooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "jetbrainsCompose" } jetbrains-compose-ui-tooling-preview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "jetbrainsCompose" } jetbrains-compose-ui-test-junit4 = { module = "org.jetbrains.compose.ui:ui-test-junit4", version.ref = "jetbrainsCompose" } +google-mlkit-genai-proofreading = { group = "com.google.mlkit", name = "genai-proofreading", version.ref = "genaiProofreading" } +google-mlkit-genai-prompt = { group = "com.google.mlkit", name = "genai-prompt", version.ref = "genaiPrompt" } +google-mlkit-genai-rewriting = { group = "com.google.mlkit", name = "genai-rewriting", version.ref = "genaiRewriting" } google-mlkit-genai-image-description = { group = "com.google.mlkit", name = "genai-image-description", version.ref = "genaiImageDescription" } google-mlkit-language-id = { group = "com.google.mlkit", name = "language-id", version.ref = "languageId" } google-mlkit-translate = { group = "com.google.mlkit", name = "translate", version.ref = "translate" }