Browse Source

Merge pull request #29 from vector-im/feature/bma/i18n

i18n
feature/bma/flipper
Benoit Marty 2 years ago committed by GitHub
parent
commit
13278e80e3
  1. 25
      .github/workflows/sync-from-external-sources.yml
  2. 1
      app/build.gradle.kts
  3. 9
      app/src/main/res/values/strings.xml
  4. 1
      features/login/build.gradle.kts
  5. 6
      features/login/src/main/java/io/element/android/x/features/login/error/ErrorFormatter.kt
  6. 6
      features/login/src/main/java/io/element/android/x/features/login/root/LoginRootScreen.kt
  7. 1
      features/logout/build.gradle.kts
  8. 12
      features/logout/src/main/java/io/element/android/x/features/logout/LogoutPreferenceScreen.kt
  9. 1
      features/onboarding/build.gradle.kts
  10. 4
      features/onboarding/src/main/java/io/element/android/x/features/onboarding/OnBoardingScreen.kt
  11. 18
      features/onboarding/src/main/java/io/element/android/x/features/onboarding/SplashCarouselStateFactory.kt
  12. 2
      features/onboarding/src/main/res/values/strings.xml
  13. 1
      features/preferences/build.gradle.kts
  14. 4
      features/preferences/src/main/java/io/element/android/x/features/preferences/root/PreferencesRootView.kt
  15. 1
      features/rageshake/build.gradle.kts
  16. 20
      features/rageshake/src/main/java/io/element/android/x/features/rageshake/bugreport/BugReportView.kt
  17. 10
      features/rageshake/src/main/java/io/element/android/x/features/rageshake/crash/ui/CrashDetectionScreen.kt
  18. 12
      features/rageshake/src/main/java/io/element/android/x/features/rageshake/detection/RageshakeDetectionView.kt
  19. 15
      features/rageshake/src/main/java/io/element/android/x/features/rageshake/preferences/RageshakePreferencesView.kt
  20. 1
      features/roomlist/build.gradle.kts
  21. 4
      features/roomlist/src/main/java/io/element/android/x/features/roomlist/components/RoomListTopBar.kt
  22. 3
      gradle/libs.versions.toml
  23. 1
      libraries/designsystem/build.gradle.kts
  24. 6
      libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/dialogs/ConfirmationDialog.kt
  25. 6
      libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/dialogs/ErrorDialog.kt
  26. 1
      libraries/textcomposer/build.gradle.kts
  27. 17
      libraries/textcomposer/src/main/java/io/element/android/x/textcomposer/RichTextComposerLayout.kt
  28. 4
      libraries/textcomposer/src/main/java/io/element/android/x/textcomposer/TextComposer.kt
  29. 15
      libraries/ui-strings/README.md
  30. 32
      libraries/ui-strings/build.gradle.kts
  31. 2
      libraries/ui-strings/src/main/AndroidManifest.xml
  32. 61
      libraries/ui-strings/src/main/res/values/array.xml
  33. 15
      libraries/ui-strings/src/main/res/values/donottranslate.xml
  34. 256
      libraries/ui-strings/src/main/res/values/strings.xml
  35. 23
      libraries/ui-strings/src/main/res/values/strings_no_weblate.xml
  36. 1
      settings.gradle.kts
  37. 57
      tools/strings/importStringsFromElement.sh

25
.github/workflows/sync-from-external-sources.yml

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
name: Sync Data From External Sources
on:
schedule:
# Every nights at 6
- cron: "0 6 * * *"
jobs:
sync-strings:
runs-on: ubuntu-latest
# Skip in forks
if: github.repository == 'vector-im/element-x-android'
# No concurrency required, runs every time on a schedule.
steps:
- uses: actions/checkout@v3
- name: Run local script
run: ./tools/strings/importStringsFromElement.sh
- name: Create Pull Request
uses: peter-evans/create-pull-request@v4
with:
commit-message: Import strings from Element Android
title: Sync strings
body: |
- Update strings from Element Android
branch: sync-strings
base: develop

1
app/build.gradle.kts

@ -20,6 +20,7 @@ @@ -20,6 +20,7 @@
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
id("io.element.android-compose-application")
alias(libs.plugins.stem)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.ksp)
alias(libs.plugins.anvil)

9
app/src/main/res/values/strings.xml

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 New Vector Ltd
~ Copyright (c) 2023 New Vector Ltd
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@ -13,7 +14,7 @@ @@ -13,7 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- The https://github.com/LikeTheSalad/android-stem requires a non empty strings.xml -->
<string name="ignored_placeholder" translatable="false" tools:ignore="UnusedResources">ignored</string>
</resources>

1
features/login/build.gradle.kts

@ -41,6 +41,7 @@ dependencies { @@ -41,6 +41,7 @@ dependencies {
implementation(project(":libraries:designsystem"))
implementation(project(":libraries:elementresources"))
implementation(libs.appyx.core)
implementation(project(":libraries:ui-strings"))
ksp(libs.showkase.processor)
testImplementation(libs.test.junit)
androidTestImplementation(libs.test.junitext)

6
features/login/src/main/java/io/element/android/x/features/login/error/ErrorFormatter.kt

@ -20,7 +20,7 @@ import androidx.compose.runtime.Composable @@ -20,7 +20,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import io.element.android.x.core.uri.isValidUrl
import io.element.android.x.features.login.root.LoginFormState
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@Composable
fun loginError(
@ -30,7 +30,7 @@ fun loginError( @@ -30,7 +30,7 @@ fun loginError(
return when {
data.login.isEmpty() -> "Please enter a login"
data.password.isEmpty() -> "Please enter a password"
throwable != null -> stringResource(id = ElementR.string.auth_invalid_login_param)
throwable != null -> stringResource(id = StringR.string.auth_invalid_login_param)
else -> "No error provided"
}
}
@ -42,7 +42,7 @@ fun changeServerError( @@ -42,7 +42,7 @@ fun changeServerError(
): String {
return when {
data.isEmpty() -> "Please enter a server URL"
!data.isValidUrl() -> stringResource(id = ElementR.string.login_error_invalid_home_server)
!data.isValidUrl() -> stringResource(id = StringR.string.login_error_invalid_home_server)
throwable != null -> "That server doesn’t seem right. Please check the address."
else -> "No error provided"
}

6
features/login/src/main/java/io/element/android/x/features/login/root/LoginRootScreen.kt

@ -62,7 +62,7 @@ import io.element.android.x.core.compose.textFieldState @@ -62,7 +62,7 @@ import io.element.android.x.core.compose.textFieldState
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.features.login.error.loginError
import io.element.android.x.matrix.core.SessionId
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -97,7 +97,7 @@ fun LoginRootScreen( @@ -97,7 +97,7 @@ fun LoginRootScreen(
val isError = state.loggedInState is LoggedInState.ErrorLoggingIn
// Title
Text(
text = stringResource(id = ElementR.string.ftue_auth_welcome_back_title),
text = stringResource(id = StringR.string.ftue_auth_welcome_back_title),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 48.dp),
@ -140,7 +140,7 @@ fun LoginRootScreen( @@ -140,7 +140,7 @@ fun LoginRootScreen(
.fillMaxWidth()
.padding(top = 60.dp),
label = {
Text(text = stringResource(id = ElementR.string.login_signin_username_hint))
Text(text = stringResource(id = StringR.string.login_signin_username_hint))
},
onValueChange = {
loginFieldState = it

1
features/logout/build.gradle.kts

@ -39,6 +39,7 @@ dependencies { @@ -39,6 +39,7 @@ dependencies {
implementation(project(":libraries:matrix"))
implementation(project(":libraries:designsystem"))
implementation(project(":libraries:elementresources"))
implementation(project(":libraries:ui-strings"))
ksp(libs.showkase.processor)
testImplementation(libs.test.junit)
androidTestImplementation(libs.test.junitext)

12
features/logout/src/main/java/io/element/android/x/features/logout/LogoutPreferenceScreen.kt

@ -30,7 +30,7 @@ import io.element.android.x.designsystem.components.ProgressDialog @@ -30,7 +30,7 @@ import io.element.android.x.designsystem.components.ProgressDialog
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.x.designsystem.components.preferences.PreferenceCategory
import io.element.android.x.designsystem.components.preferences.PreferenceText
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@Composable
fun LogoutPreferenceView(
@ -55,9 +55,9 @@ fun LogoutPreferenceView( @@ -55,9 +55,9 @@ fun LogoutPreferenceView(
// Log out confirmation dialog
if (openDialog.value) {
ConfirmationDialog(
title = stringResource(id = ElementR.string.action_sign_out),
content = stringResource(id = ElementR.string.action_sign_out_confirmation_simple),
submitText = stringResource(id = ElementR.string.action_sign_out),
title = stringResource(id = StringR.string.action_sign_out),
content = stringResource(id = StringR.string.action_sign_out_confirmation_simple),
submitText = stringResource(id = StringR.string.action_sign_out),
onCancelClicked = {
openDialog.value = false
},
@ -80,9 +80,9 @@ fun LogoutPreferenceView( @@ -80,9 +80,9 @@ fun LogoutPreferenceView(
fun LogoutPreferenceContent(
onClick: () -> Unit = {},
) {
PreferenceCategory(title = stringResource(id = ElementR.string.settings_general_title)) {
PreferenceCategory(title = stringResource(id = StringR.string.settings_general_title)) {
PreferenceText(
title = stringResource(id = ElementR.string.action_sign_out),
title = stringResource(id = StringR.string.action_sign_out),
icon = Icons.Default.Logout,
onClick = onClick
)

1
features/onboarding/build.gradle.kts

@ -28,6 +28,7 @@ android { @@ -28,6 +28,7 @@ android {
dependencies {
implementation(project(":libraries:core"))
implementation(project(":libraries:elementresources"))
implementation(project(":libraries:ui-strings"))
implementation(project(":libraries:designsystem"))
implementation(project(":libraries:architecture"))
implementation(libs.accompanist.pager)

4
features/onboarding/src/main/java/io/element/android/x/features/onboarding/OnBoardingScreen.kt

@ -52,7 +52,7 @@ import com.google.accompanist.pager.rememberPagerState @@ -52,7 +52,7 @@ import com.google.accompanist.pager.rememberPagerState
import io.element.android.x.designsystem.components.VectorButton
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@OptIn(ExperimentalPagerApi::class)
@Composable
@ -120,7 +120,7 @@ fun OnBoardingScreen( @@ -120,7 +120,7 @@ fun OnBoardingScreen(
)
*/
VectorButton(
text = stringResource(id = ElementR.string.login_splash_submit),
text = stringResource(id = StringR.string.login_splash_submit),
onClick = {
onSignIn()
},

18
features/onboarding/src/main/java/io/element/android/x/features/onboarding/SplashCarouselStateFactory.kt

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
package io.element.android.x.features.onboarding
import androidx.annotation.DrawableRes
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
class SplashCarouselStateFactory {
fun create(): SplashCarouselState {
@ -32,8 +32,8 @@ class SplashCarouselStateFactory { @@ -32,8 +32,8 @@ class SplashCarouselStateFactory {
return SplashCarouselState(
listOf(
SplashCarouselState.Item(
ElementR.string.ftue_auth_carousel_secure_title,
ElementR.string.ftue_auth_carousel_secure_body,
StringR.string.ftue_auth_carousel_secure_title,
StringR.string.ftue_auth_carousel_secure_body,
hero(
R.drawable.ic_splash_conversations,
R.drawable.ic_splash_conversations_dark
@ -41,20 +41,20 @@ class SplashCarouselStateFactory { @@ -41,20 +41,20 @@ class SplashCarouselStateFactory {
background(R.drawable.bg_carousel_page_1)
),
SplashCarouselState.Item(
ElementR.string.ftue_auth_carousel_control_title,
ElementR.string.ftue_auth_carousel_control_body,
StringR.string.ftue_auth_carousel_control_title,
StringR.string.ftue_auth_carousel_control_body,
hero(R.drawable.ic_splash_control, R.drawable.ic_splash_control_dark),
background(R.drawable.bg_carousel_page_2)
),
SplashCarouselState.Item(
ElementR.string.ftue_auth_carousel_encrypted_title,
ElementR.string.ftue_auth_carousel_encrypted_body,
StringR.string.ftue_auth_carousel_encrypted_title,
StringR.string.ftue_auth_carousel_encrypted_body,
hero(R.drawable.ic_splash_secure, R.drawable.ic_splash_secure_dark),
background(R.drawable.bg_carousel_page_3)
),
SplashCarouselState.Item(
collaborationTitle(),
ElementR.string.ftue_auth_carousel_workplace_body,
StringR.string.ftue_auth_carousel_workplace_body,
hero(
R.drawable.ic_splash_collaboration,
R.drawable.ic_splash_collaboration_dark
@ -68,7 +68,7 @@ class SplashCarouselStateFactory { @@ -68,7 +68,7 @@ class SplashCarouselStateFactory {
private fun collaborationTitle(): Int {
return when {
true -> R.string.cut_the_slack_from_teams
else -> ElementR.string.ftue_auth_carousel_workplace_title
else -> StringR.string.ftue_auth_carousel_workplace_title
}
}
}

2
features/onboarding/src/main/res/values/strings.xml

@ -16,5 +16,5 @@ @@ -16,5 +16,5 @@
-->
<resources>
<string name="cut_the_slack_from_teams">Cut the slack from teams.</string>
<string name="cut_the_slack_from_teams" translatable="false">Cut the slack from teams.</string>
</resources>

1
features/preferences/build.gradle.kts

@ -42,6 +42,7 @@ dependencies { @@ -42,6 +42,7 @@ dependencies {
implementation(project(":features:logout"))
implementation(project(":libraries:designsystem"))
implementation(project(":libraries:elementresources"))
implementation(project(":libraries:ui-strings"))
implementation(libs.datetime)
implementation(libs.accompanist.placeholder)
testImplementation(libs.test.junit)

4
features/preferences/src/main/java/io/element/android/x/features/preferences/root/PreferencesRootView.kt

@ -22,12 +22,12 @@ import androidx.compose.ui.res.stringResource @@ -22,12 +22,12 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.x.architecture.Async
import io.element.android.x.designsystem.components.preferences.PreferenceView
import io.element.android.x.element.resources.R
import io.element.android.x.features.logout.LogoutPreferenceState
import io.element.android.x.features.logout.LogoutPreferenceView
import io.element.android.x.features.preferences.user.UserPreferences
import io.element.android.x.features.rageshake.preferences.RageshakePreferencesState
import io.element.android.x.features.rageshake.preferences.RageshakePreferencesView
import io.element.android.x.ui.strings.R as StringR
@Composable
fun PreferencesRootView(
@ -41,7 +41,7 @@ fun PreferencesRootView( @@ -41,7 +41,7 @@ fun PreferencesRootView(
PreferenceView(
modifier = modifier,
onBackPressed = onBackPressed,
title = stringResource(id = R.string.settings)
title = stringResource(id = StringR.string.settings)
) {
UserPreferences(state.myUser)
RageshakePreferencesView(

1
features/rageshake/build.gradle.kts

@ -39,6 +39,7 @@ dependencies { @@ -39,6 +39,7 @@ dependencies {
implementation(project(":anvilannotations"))
implementation(project(":libraries:designsystem"))
implementation(project(":libraries:elementresources"))
implementation(project(":libraries:ui-strings"))
implementation(libs.squareup.seismic)
implementation(libs.androidx.datastore.preferences)
implementation(libs.coil)

20
features/rageshake/src/main/java/io/element/android/x/features/rageshake/bugreport/BugReportView.kt

@ -56,7 +56,7 @@ import io.element.android.x.core.compose.textFieldState @@ -56,7 +56,7 @@ import io.element.android.x.core.compose.textFieldState
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.LabelledCheckbox
import io.element.android.x.designsystem.components.dialogs.ErrorDialog
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -96,7 +96,7 @@ fun BugReportView( @@ -96,7 +96,7 @@ fun BugReportView(
val isFormEnabled = state.sending !is Async.Loading
// Title
Text(
text = stringResource(id = ElementR.string.send_bug_report),
text = stringResource(id = StringR.string.send_bug_report),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 16.dp),
@ -106,7 +106,7 @@ fun BugReportView( @@ -106,7 +106,7 @@ fun BugReportView(
)
// Form
Text(
text = stringResource(id = ElementR.string.send_bug_report_description),
text = stringResource(id = StringR.string.send_bug_report_description),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 16.dp),
@ -123,10 +123,10 @@ fun BugReportView( @@ -123,10 +123,10 @@ fun BugReportView(
.padding(top = 16.dp),
enabled = isFormEnabled,
label = {
Text(text = stringResource(id = ElementR.string.send_bug_report_placeholder))
Text(text = stringResource(id = StringR.string.send_bug_report_placeholder))
},
supportingText = {
Text(text = stringResource(id = ElementR.string.send_bug_report_description_in_english))
Text(text = stringResource(id = StringR.string.send_bug_report_description_in_english))
},
onValueChange = {
descriptionFieldState = it
@ -143,28 +143,28 @@ fun BugReportView( @@ -143,28 +143,28 @@ fun BugReportView(
checked = state.formState.sendLogs,
onCheckedChange = { eventSink(BugReportEvents.SetSendLog(it)) },
enabled = isFormEnabled,
text = stringResource(id = ElementR.string.send_bug_report_include_logs)
text = stringResource(id = StringR.string.send_bug_report_include_logs)
)
if (state.hasCrashLogs) {
LabelledCheckbox(
checked = state.formState.sendCrashLogs,
onCheckedChange = { eventSink(BugReportEvents.SetSendCrashLog(it)) },
enabled = isFormEnabled,
text = stringResource(id = ElementR.string.send_bug_report_include_crash_logs)
text = stringResource(id = StringR.string.send_bug_report_include_crash_logs)
)
}
LabelledCheckbox(
checked = state.formState.canContact,
onCheckedChange = { eventSink(BugReportEvents.SetCanContact(it)) },
enabled = isFormEnabled,
text = stringResource(id = ElementR.string.you_may_contact_me)
text = stringResource(id = StringR.string.you_may_contact_me)
)
if (state.screenshotUri != null) {
LabelledCheckbox(
checked = state.formState.sendScreenshot,
onCheckedChange = { eventSink(BugReportEvents.SetSendScreenshot(it)) },
enabled = isFormEnabled,
text = stringResource(id = ElementR.string.send_bug_report_include_screenshot)
text = stringResource(id = StringR.string.send_bug_report_include_screenshot)
)
if (state.formState.sendScreenshot) {
Box(
@ -191,7 +191,7 @@ fun BugReportView( @@ -191,7 +191,7 @@ fun BugReportView(
.fillMaxWidth()
.padding(vertical = 32.dp)
) {
Text(text = stringResource(id = ElementR.string.action_send))
Text(text = stringResource(id = StringR.string.action_send))
}
}
when (state.sending) {

10
features/rageshake/src/main/java/io/element/android/x/features/rageshake/crash/ui/CrashDetectionScreen.kt

@ -22,7 +22,7 @@ import androidx.compose.ui.tooling.preview.Preview @@ -22,7 +22,7 @@ import androidx.compose.ui.tooling.preview.Preview
import io.element.android.x.core.compose.LogCompositions
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@Composable
fun CrashDetectionView(
@ -53,10 +53,10 @@ fun CrashDetectionContent( @@ -53,10 +53,10 @@ fun CrashDetectionContent(
onDismiss: () -> Unit = { },
) {
ConfirmationDialog(
title = stringResource(id = ElementR.string.send_bug_report),
content = stringResource(id = ElementR.string.send_bug_report_app_crashed),
submitText = stringResource(id = ElementR.string.yes),
cancelText = stringResource(id = ElementR.string.no),
title = stringResource(id = StringR.string.send_bug_report),
content = stringResource(id = StringR.string.send_bug_report_app_crashed),
submitText = stringResource(id = StringR.string.yes),
cancelText = stringResource(id = StringR.string.no),
onCancelClicked = onNoClicked,
onSubmitClicked = onYesClicked,
onDismiss = onDismiss,

12
features/rageshake/src/main/java/io/element/android/x/features/rageshake/detection/RageshakeDetectionView.kt

@ -30,7 +30,7 @@ import io.element.android.x.core.screenshot.ImageResult @@ -30,7 +30,7 @@ import io.element.android.x.core.screenshot.ImageResult
import io.element.android.x.core.screenshot.screenshot
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@Composable
fun RageshakeDetectionView(
@ -83,11 +83,11 @@ fun RageshakeDialogContent( @@ -83,11 +83,11 @@ fun RageshakeDialogContent(
onYesClicked: () -> Unit = { },
) {
ConfirmationDialog(
title = stringResource(id = ElementR.string.send_bug_report),
content = stringResource(id = ElementR.string.send_bug_report_alert_message),
thirdButtonText = stringResource(id = ElementR.string.action_disable),
submitText = stringResource(id = ElementR.string.yes),
cancelText = stringResource(id = ElementR.string.no),
title = stringResource(id = StringR.string.send_bug_report),
content = stringResource(id = StringR.string.send_bug_report_alert_message),
thirdButtonText = stringResource(id = StringR.string.action_disable),
submitText = stringResource(id = StringR.string.yes),
cancelText = stringResource(id = StringR.string.no),
onCancelClicked = onNoClicked,
onThirdButtonClicked = onDisableClicked,
onSubmitClicked = onYesClicked,

15
features/rageshake/src/main/java/io/element/android/x/features/rageshake/preferences/RageshakePreferencesView.kt

@ -27,7 +27,7 @@ import io.element.android.x.designsystem.components.preferences.PreferenceCatego @@ -27,7 +27,7 @@ import io.element.android.x.designsystem.components.preferences.PreferenceCatego
import io.element.android.x.designsystem.components.preferences.PreferenceSlide
import io.element.android.x.designsystem.components.preferences.PreferenceSwitch
import io.element.android.x.designsystem.components.preferences.PreferenceText
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@Composable
fun RageshakePreferencesView(
@ -44,24 +44,23 @@ fun RageshakePreferencesView( @@ -44,24 +44,23 @@ fun RageshakePreferencesView(
}
Column(modifier = modifier) {
PreferenceCategory(title = stringResource(id = ElementR.string.send_bug_report)) {
PreferenceCategory(title = stringResource(id = StringR.string.send_bug_report)) {
PreferenceText(
title = stringResource(id = ElementR.string.send_bug_report),
title = stringResource(id = StringR.string.send_bug_report),
icon = Icons.Default.BugReport,
onClick = onOpenRageshake
)
}
PreferenceCategory(title = stringResource(id = ElementR.string.settings_rageshake)) {
PreferenceCategory(title = stringResource(id = StringR.string.settings_rageshake)) {
if (state.isSupported) {
PreferenceSwitch(
title = stringResource(id = ElementR.string.send_bug_report_rage_shake),
title = stringResource(id = StringR.string.send_bug_report_rage_shake),
isChecked = state.isEnabled,
onCheckedChange = ::onEnabledChanged
)
PreferenceSlide(
title = stringResource(id = ElementR.string.settings_rageshake_detection_threshold),
// summary = stringResource(id = ElementR.string.settings_rageshake_detection_threshold_summary),
title = stringResource(id = StringR.string.settings_rageshake_detection_threshold),
// summary = stringResource(id = StringR.string.settings_rageshake_detection_threshold_summary),
value = state.sensitivity,
enabled = state.isEnabled,
steps = 3 /* 5 possible values - steps are in ]0, 1[ */,

1
features/roomlist/build.gradle.kts

@ -41,6 +41,7 @@ dependencies { @@ -41,6 +41,7 @@ dependencies {
implementation(project(":libraries:designsystem"))
implementation(libs.appyx.core)
implementation(project(":libraries:elementresources"))
implementation(project(":libraries:ui-strings"))
implementation(libs.datetime)
implementation(libs.accompanist.placeholder)
testImplementation(libs.test.junit)

4
features/roomlist/src/main/java/io/element/android/x/features/roomlist/components/RoomListTopBar.kt

@ -48,6 +48,7 @@ import androidx.compose.ui.focus.FocusRequester @@ -48,6 +48,7 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
@ -55,6 +56,7 @@ import io.element.android.x.core.compose.LogCompositions @@ -55,6 +56,7 @@ import io.element.android.x.core.compose.LogCompositions
import io.element.android.x.core.compose.textFieldState
import io.element.android.x.designsystem.components.avatar.Avatar
import io.element.android.x.matrix.ui.model.MatrixUser
import io.element.android.x.ui.strings.R as StringR
@Composable
fun RoomListTopBar(
@ -185,7 +187,7 @@ private fun DefaultRoomListTopBar( @@ -185,7 +187,7 @@ private fun DefaultRoomListTopBar(
title = {
Text(
fontWeight = FontWeight.Bold,
text = "All Chats"
text = stringResource(id = StringR.string.all_chats)
)
},
navigationIcon = {

3
gradle/libs.versions.toml

@ -51,6 +51,7 @@ jsoup = "1.15.3" @@ -51,6 +51,7 @@ jsoup = "1.15.3"
appyx = "1.0.1"
seismic = "1.0.3"
dependencycheck = "7.4.4"
stem = "2.2.3"
# DI
dagger = "2.43"
@ -150,3 +151,5 @@ ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } @@ -150,3 +151,5 @@ ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
molecule = {id = "app.cash.molecule", version.ref = "molecule"}
dependencygraph = { id = "com.savvasdalkitsis.module-dependency-graph", version.ref = "dependencygraph" }
dependencycheck = { id = "org.owasp.dependencycheck", version.ref = "dependencycheck" }
stem = { id = "com.likethesalad.stem", version.ref = "stem" }
stemlibrary = { id = "com.likethesalad.stem-library", version.ref = "stem" }

1
libraries/designsystem/build.gradle.kts

@ -29,6 +29,7 @@ android { @@ -29,6 +29,7 @@ android {
implementation(libs.coil.compose)
implementation(libs.accompanist.systemui)
implementation(project(":libraries:elementresources"))
implementation(project(":libraries:ui-strings"))
ksp(libs.showkase.processor)
}
}

6
libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/dialogs/ConfirmationDialog.kt

@ -29,15 +29,15 @@ import androidx.compose.ui.Modifier @@ -29,15 +29,15 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@Composable
fun ConfirmationDialog(
title: String,
content: String,
modifier: Modifier = Modifier,
submitText: String = stringResource(id = ElementR.string.ok),
cancelText: String = stringResource(id = ElementR.string.action_cancel),
submitText: String = stringResource(id = StringR.string.ok),
cancelText: String = stringResource(id = StringR.string.action_cancel),
thirdButtonText: String? = null,
onSubmitClicked: () -> Unit = {},
onCancelClicked: () -> Unit = {},

6
libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/dialogs/ErrorDialog.kt

@ -28,14 +28,14 @@ import androidx.compose.ui.Modifier @@ -28,14 +28,14 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@Composable
fun ErrorDialog(
content: String,
modifier: Modifier = Modifier,
title: String = stringResource(id = ElementR.string.dialog_title_error),
submitText: String = stringResource(id = ElementR.string.ok),
title: String = stringResource(id = StringR.string.dialog_title_error),
submitText: String = stringResource(id = StringR.string.ok),
onDismiss: () -> Unit = {},
) {
AlertDialog(

1
libraries/textcomposer/build.gradle.kts

@ -31,6 +31,7 @@ android { @@ -31,6 +31,7 @@ android {
dependencies {
implementation(project(":libraries:elementresources"))
implementation(project(":libraries:ui-strings"))
implementation(project(":libraries:core"))
implementation(project(":libraries:matrix"))
implementation(libs.wysiwyg)

17
libraries/textcomposer/src/main/java/io/element/android/x/textcomposer/RichTextComposerLayout.kt

@ -45,12 +45,13 @@ import io.element.android.wysiwyg.inputhandlers.models.InlineFormat @@ -45,12 +45,13 @@ import io.element.android.wysiwyg.inputhandlers.models.InlineFormat
import io.element.android.x.core.ui.DimensionConverter
import io.element.android.x.core.ui.hideKeyboard
import io.element.android.x.core.ui.showKeyboard
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.textcomposer.databinding.ComposerRichTextLayoutBinding
import io.element.android.x.textcomposer.databinding.ViewRichTextMenuButtonBinding
import io.element.android.x.textcomposer.tools.setTextIfDifferent
import uniffi.wysiwyg_composer.ActionState
import uniffi.wysiwyg_composer.ComposerAction
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
// Imported from Element Android
class RichTextComposerLayout @JvmOverloads constructor(
@ -248,28 +249,28 @@ class RichTextComposerLayout @JvmOverloads constructor( @@ -248,28 +249,28 @@ class RichTextComposerLayout @JvmOverloads constructor(
private fun setupRichTextMenu() {
addRichTextMenuItem(
R.drawable.ic_composer_bold,
ElementR.string.rich_text_editor_format_bold,
StringR.string.rich_text_editor_format_bold,
ComposerAction.BOLD
) {
views.richTextComposerEditText.toggleInlineFormat(InlineFormat.Bold)
}
addRichTextMenuItem(
R.drawable.ic_composer_italic,
ElementR.string.rich_text_editor_format_italic,
StringR.string.rich_text_editor_format_italic,
ComposerAction.ITALIC
) {
views.richTextComposerEditText.toggleInlineFormat(InlineFormat.Italic)
}
addRichTextMenuItem(
R.drawable.ic_composer_underlined,
ElementR.string.rich_text_editor_format_underline,
StringR.string.rich_text_editor_format_underline,
ComposerAction.UNDERLINE
) {
views.richTextComposerEditText.toggleInlineFormat(InlineFormat.Underline)
}
addRichTextMenuItem(
R.drawable.ic_composer_strikethrough,
ElementR.string.rich_text_editor_format_strikethrough,
StringR.string.rich_text_editor_format_strikethrough,
ComposerAction.STRIKE_THROUGH
) {
views.richTextComposerEditText.toggleInlineFormat(InlineFormat.StrikeThrough)
@ -495,16 +496,16 @@ class RichTextComposerLayout @JvmOverloads constructor( @@ -495,16 +496,16 @@ class RichTextComposerLayout @JvmOverloads constructor(
*/
views.plainTextComposerEditText.setText(text)
}
views.sendButton.contentDescription = resources.getString(ElementR.string.action_send)
views.sendButton.contentDescription = resources.getString(StringR.string.action_send)
hasRelatedMessage = false
}
views.sendButton.apply {
if (mode is MessageComposerMode.Edit) {
contentDescription = resources.getString(ElementR.string.action_save)
contentDescription = resources.getString(StringR.string.action_save)
setImageResource(R.drawable.ic_composer_rich_text_save)
} else {
contentDescription = resources.getString(ElementR.string.action_send)
contentDescription = resources.getString(StringR.string.action_send)
setImageResource(R.drawable.ic_rich_composer_send)
}
}

4
libraries/textcomposer/src/main/java/io/element/android/x/textcomposer/TextComposer.kt

@ -34,7 +34,7 @@ import androidx.compose.ui.unit.sp @@ -34,7 +34,7 @@ import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.ui.strings.R as StringR
@Composable
fun TextComposer(
@ -137,7 +137,7 @@ private fun MessageComposerView.setup(isDarkMode: Boolean, composerMode: Message @@ -137,7 +137,7 @@ private fun MessageComposerView.setup(isDarkMode: Boolean, composerMode: Message
}
editText.setTextColor(editTextColor)
editText.setHintTextColor(editTextColor)
editText.setHint(ElementR.string.room_message_placeholder)
editText.setHint(StringR.string.room_message_placeholder)
emojiButton?.isVisible = true
sendButton.isVisible = true
editText.maxLines = MessageComposerView.MAX_LINES_WHEN_COLLAPSED

15
libraries/ui-strings/README.md

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
## Module ui-strings
This module contains strings from Element Android.
The content of this module will be keep synced by the script `rootDir/tools/strings/importStringsFromElement.sh`, which is run daily by a GitHub action.
### Adding new strings
Add new strings to the file `./src/main/res/values/new_strings.xml`, or your new strings will be erased on the next sync.
Also, new strings must be added to Element Android to give a chance to get translation.
### Long term
In the future, Weblate will be synced directly with this project.

32
libraries/ui-strings/build.gradle.kts

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
id("io.element.android-library")
alias(libs.plugins.stemlibrary)
}
android {
namespace = "io.element.android.x.ui.strings"
}
// forcing the stem string template generator to be cacheable, without this the templates
// are regenerated causing the app module to recompile its sources
tasks.withType(com.likethesalad.android.templates.common.tasks.BaseTask::class.java) {
outputs.cacheIf { true }
}

2
libraries/ui-strings/src/main/AndroidManifest.xml

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

61
libraries/ui-strings/src/main/res/values/array.xml

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- media settings -->
<string-array name="compression_levels">
<item>@string/compression_opt_list_choose</item>
<item>@string/compression_opt_list_original</item>
<item>@string/compression_opt_list_large</item>
<item>@string/compression_opt_list_medium</item>
<item>@string/compression_opt_list_small</item>
</string-array>
<string-array name="compression_level_values">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</string-array>
<string-array name="media_sources">
<item>@string/media_source_choose</item>
<item>@string/option_send_files</item>
<item>@string/option_send_voice</item>
<item>@string/option_send_sticker</item>
<item>@string/option_take_photo</item>
<item>@string/option_take_video</item>
</string-array>
<string-array name="media_source_values">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>
<!-- Room settings notification -->
<!-- Theme -->
<string-array name="theme_entries">
<item>@string/system_theme</item>
<item>@string/light_theme</item>
<item>@string/dark_theme</item>
<item>@string/black_theme</item>
</string-array>
<string-array name="theme_values">
<item>system</item>
<item>light</item>
<item>dark</item>
<item>black</item>
</string-array>
<!-- media saving choice list -->
<string-array name="media_saving_choice">
<item>@string/media_saving_period_3_days</item>
<item>@string/media_saving_period_1_week</item>
<item>@string/media_saving_period_1_month</item>
<item>@string/media_saving_period_forever</item>
</string-array>
</resources>

15
libraries/ui-strings/src/main/res/values/donottranslate.xml

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ellipsis" translatable="false"></string>
<string name="no_value_placeholder" translatable="false"></string>
<!-- Temporary string -->
<string name="not_implemented" translatable="false">Not implemented yet in ${app_name}</string>
<!-- onboarding english only word play -->
<string name="cut_the_slack_from_teams" translatable="false">Cut the slack from teams.</string>
<!-- WIP -->
<string name="location_map_view_copyright" translatable="false">© MapTiler © OpenStreetMap contributors</string>
</resources>

256
libraries/elementresources/src/main/res/values/strings.xml → libraries/ui-strings/src/main/res/values/strings.xml

@ -1,20 +1,4 @@ @@ -1,20 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 New Vector Ltd
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Cross feature -->
@ -150,6 +134,9 @@ @@ -150,6 +134,9 @@
<string name="notice_crypto_unable_to_decrypt">** Unable to decrypt: %s **</string>
<string name="notice_crypto_error_unknown_inbound_session_id">The sender\'s device has not sent us the keys for this message.</string>
<string name="notice_voice_broadcast_ended">%1$s ended a voice broadcast.</string>
<string name="notice_voice_broadcast_ended_by_you">You ended a voice broadcast.</string>
<!-- Messages -->
<!-- Room Screen -->
@ -209,7 +196,7 @@ @@ -209,7 +196,7 @@
<string name="initial_sync_start_importing_account_data">Initial sync:\nImporting account data</string>
<string name="initial_sync_request_title">Initial sync request</string>
<string name="initial_sync_request_content">ElementX needs to perform a clear cache to be up to date, for the following reason:\n%s\n\nNote that this action will restart the app and it may take some time.</string>
<string name="initial_sync_request_content">${app_name} needs to perform a clear cache to be up to date, for the following reason:\n%s\n\nNote that this action will restart the app and it may take some time.</string>
<string name="initial_sync_request_reason_unignored_users">- Some users have been unignored</string>
<string name="event_status_sent_message">Message sent</string>
@ -432,6 +419,7 @@ @@ -432,6 +419,7 @@
<string name="action_got_it">Got it</string>
<string name="action_select_all">Select all</string>
<string name="action_deselect_all">Deselect all</string>
<string name="action_stop">Yes, Stop</string>
<string name="copied_to_clipboard">Copied to clipboard</string>
@ -537,8 +525,8 @@ @@ -537,8 +525,8 @@
<string name="start_voice_call_prompt_msg">Are you sure that you want to start a voice call?</string>
<string name="start_video_call_prompt_msg">Are you sure that you want to start a video call?</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="call_failed_no_connection">ElementX Call Failed</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="call_failed_no_connection">${app_name} Call Failed</string>
<string name="call_failed_no_connection_description">Failed to establish real time connection.\nPlease ask the administrator of your homeserver to configure a TURN server in order for calls to work reliably.</string>
<string name="call_select_sound_device">Select Sound Device</string>
@ -600,8 +588,8 @@ @@ -600,8 +588,8 @@
<!-- request again e2e key -->
<string name="e2e_re_request_encryption_key">Re-request encryption keys from your other sessions.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="e2e_re_request_encryption_key_dialog_content">Please launch ElementX on another device that can decrypt the message so it can send the keys to this session.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="e2e_re_request_encryption_key_dialog_content">Please launch ${app_name} on another device that can decrypt the message so it can send the keys to this session.</string>
<!-- Mels -->
<plurals name="membership_changes">
@ -621,8 +609,8 @@ @@ -621,8 +609,8 @@
<string name="settings_call_category">Calls</string>
<string name="settings_call_show_confirmation_dialog_title">Prevent accidental call</string>
<string name="settings_call_show_confirmation_dialog_summary">Ask for confirmation before starting a call</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_call_ringtone_use_app_ringtone">Use default ElementX ringtone for incoming calls</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_call_ringtone_use_app_ringtone">Use default ${app_name} ringtone for incoming calls</string>
<string name="settings_call_ringtone_title">Incoming call ringtone</string>
<string name="settings_call_ringtone_dialog_title">Select ringtone for calls:</string>
@ -659,12 +647,12 @@ @@ -659,12 +647,12 @@
<!-- permissions Android M -->
<string name="permissions_rationale_popup_title">Information</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="permissions_rationale_msg_record_audio">ElementX needs permission to access your microphone to perform audio calls.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="permissions_rationale_msg_camera_and_audio">ElementX needs permission to access your camera and your microphone to perform video calls.\n\nPlease allow access on the next pop-ups to be able to make the call.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="permissions_rationale_msg_notification">ElementX needs permission to display notifications. Notifications can display your messages, your invitations, etc.\n\nPlease allow access on the next pop-ups to be able to view notification.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="permissions_rationale_msg_record_audio">${app_name} needs permission to access your microphone to perform audio calls.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="permissions_rationale_msg_camera_and_audio">${app_name} needs permission to access your camera and your microphone to perform video calls.\n\nPlease allow access on the next pop-ups to be able to make the call.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="permissions_rationale_msg_notification">${app_name} needs permission to display notifications. Notifications can display your messages, your invitations, etc.\n\nPlease allow access on the next pop-ups to be able to view notification.</string>
<string name="permissions_denied_qr_code">To scan a QR code, you need to allow camera access.</string>
<string name="permissions_denied_add_contact">Allow permission to access your contacts.</string>
@ -884,7 +872,7 @@ @@ -884,7 +872,7 @@
<string name="settings_troubleshoot_test_system_settings_title">System Settings.</string>
<string name="settings_troubleshoot_test_system_settings_success">Notifications are enabled in the system settings.</string>
<string name="settings_troubleshoot_test_system_settings_failed">Notifications are disabled in the system settings.\nPlease check system settings.</string>
<string name="settings_troubleshoot_test_system_settings_permission_failed">ElementX needs the permission to show notifications.\nPlease grant the permission.</string>
<string name="settings_troubleshoot_test_system_settings_permission_failed">${app_name} needs the permission to show notifications.\nPlease grant the permission.</string>
<string name="open_settings">Open Settings</string>
<string name="grant_permission">Grant Permission</string>
@ -895,8 +883,8 @@ @@ -895,8 +883,8 @@
<string name="settings_troubleshoot_test_device_settings_title">Session Settings.</string>
<string name="settings_troubleshoot_test_device_settings_success">Notifications are enabled for this session.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_device_settings_failed">Notifications are not enabled for this session.\nPlease check the ElementX settings.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_device_settings_failed">Notifications are not enabled for this session.\nPlease check the ${app_name} settings.</string>
<string name="settings_troubleshoot_test_device_settings_quickfix">Enable</string>
<string name="settings_troubleshoot_test_bing_settings_title">Custom Settings.</string>
@ -905,19 +893,19 @@ @@ -905,19 +893,19 @@
<string name="settings_troubleshoot_test_play_services_title">Play Services Check</string>
<string name="settings_troubleshoot_test_play_services_success">Google Play Services APK is available and up-to-date.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_play_services_failed">ElementX uses Google Play Services to deliver push messages but it doesn’t seem to be configured correctly:\n%1$s</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_play_services_failed">${app_name} uses Google Play Services to deliver push messages but it doesn’t seem to be configured correctly:\n%1$s</string>
<string name="settings_troubleshoot_test_play_services_quickfix">Fix Play Services</string>
<string name="settings_troubleshoot_test_fcm_title">Firebase Token</string>
<string name="settings_troubleshoot_test_fcm_success">FCM token successfully retrieved:\n%1$s</string>
<string name="settings_troubleshoot_test_fcm_failed">Failed to retrieved FCM token:\n%1$s</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_fcm_failed_too_many_registration">[%1$s]\nThis error is out of control of ElementX and according to Google, this error indicates that the device has too many apps registered with FCM. The error only occurs in cases where there are extreme numbers of apps, so it should not affect the average user.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_fcm_failed_service_not_available">[%1$s]\nThis error is out of control of ElementX. It can occur for several reasons. Maybe it will work if you retry later, you can also check that Google Play Service is not restricted in data usage in the system settings, or that your device clock is correct, or it can happen on custom ROM.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_fcm_failed_account_missing">[%1$s]\nThis error is out of control of ElementX. There is no Google account on the phone. Please open the account manager and add a Google account.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_fcm_failed_too_many_registration">[%1$s]\nThis error is out of control of ${app_name} and according to Google, this error indicates that the device has too many apps registered with FCM. The error only occurs in cases where there are extreme numbers of apps, so it should not affect the average user.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_fcm_failed_service_not_available">[%1$s]\nThis error is out of control of ${app_name}. It can occur for several reasons. Maybe it will work if you retry later, you can also check that Google Play Service is not restricted in data usage in the system settings, or that your device clock is correct, or it can happen on custom ROM.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_fcm_failed_account_missing">[%1$s]\nThis error is out of control of ${app_name}. There is no Google account on the phone. Please open the account manager and add a Google account.</string>
<string name="settings_troubleshoot_test_fcm_failed_account_missing_quick_fix">Add Account</string>
<string name="settings_troubleshoot_test_token_registration_title">Token Registration</string>
@ -939,20 +927,20 @@ @@ -939,20 +927,20 @@
<string name="settings_troubleshoot_test_service_boot_title">Start on boot</string>
<string name="settings_troubleshoot_test_service_boot_success">Service will start when the device is restarted.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_service_boot_failed">The service will not start when the device is restarted, you will not receive notifications until ElementX has been opened once.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_service_boot_failed">The service will not start when the device is restarted, you will not receive notifications until ${app_name} has been opened once.</string>
<string name="settings_troubleshoot_test_service_boot_quickfix">Enable Start on boot</string>
<string name="settings_troubleshoot_test_bg_restricted_title">Check background restrictions</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_bg_restricted_success">Background restrictions are disabled for ElementX. This test should be run using mobile data (no WIFI).\n%1$s</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_bg_restricted_failed">Background restrictions are enabled for ElementX.\nWork that the app tries to do will be aggressively restricted while it is in the background, and this could affect notifications.\n%1$s</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_bg_restricted_success">Background restrictions are disabled for ${app_name}. This test should be run using mobile data (no WIFI).\n%1$s</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_bg_restricted_failed">Background restrictions are enabled for ${app_name}.\nWork that the app tries to do will be aggressively restricted while it is in the background, and this could affect notifications.\n%1$s</string>
<string name="settings_troubleshoot_test_bg_restricted_quickfix">Disable restrictions</string>
<string name="settings_troubleshoot_test_battery_title">Battery Optimization</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_battery_success">ElementX is not affected by Battery Optimization.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_troubleshoot_test_battery_success">${app_name} is not affected by Battery Optimization.</string>
<string name="settings_troubleshoot_test_battery_failed">If a user leaves a device unplugged and stationary for a period of time, with the screen off, the device enters Doze mode. This prevents apps from accessing the network and defers their jobs, syncs, and standard alarms. </string>
<string name="settings_troubleshoot_test_battery_quickfix">Ignore Optimization</string>
@ -992,11 +980,11 @@ @@ -992,11 +980,11 @@
<string name="settings_background_sync">Background synchronization</string>
<string name="settings_background_fdroid_sync_mode">Background Sync Mode</string>
<string name="settings_background_fdroid_sync_mode_battery">Optimized for battery</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_background_fdroid_sync_mode_battery_description">ElementX will sync in background in way that preserves the device’s limited resources (battery).\nDepending on your device resource state, the sync may be deferred by the operating system.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_background_fdroid_sync_mode_battery_description">${app_name} will sync in background in way that preserves the device’s limited resources (battery).\nDepending on your device resource state, the sync may be deferred by the operating system.</string>
<string name="settings_background_fdroid_sync_mode_real_time">Optimized for real time</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_background_fdroid_sync_mode_real_time_description">ElementX will sync in background periodically at precise time (configurable).\nThis will impact radio and battery usage, there will be a permanent notification displayed stating that ElementX is listening for events.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_background_fdroid_sync_mode_real_time_description">${app_name} will sync in background periodically at precise time (configurable).\nThis will impact radio and battery usage, there will be a permanent notification displayed stating that ${app_name} is listening for events.</string>
<string name="settings_background_fdroid_sync_mode_disabled">No background sync</string>
<string name="settings_background_fdroid_sync_mode_disabled_description">You will not be notified of incoming messages when the app is in background.</string>
@ -1048,6 +1036,8 @@ @@ -1048,6 +1036,8 @@
<string name="settings_chat_effects_description">Use /confetti command or send a message containing ❄ or 🎉</string>
<string name="settings_autoplay_animated_images_title">Autoplay animated images</string>
<string name="settings_autoplay_animated_images_summary">Play animated images in the timeline as soon as they are visible</string>
<string name="settings_enable_direct_share_title">Enable direct share</string>
<string name="settings_enable_direct_share_summary">Show recent chats in the system share menu</string>
<string name="settings_show_join_leave_messages">Show join and leave events</string>
<string name="settings_show_join_leave_messages_summary">Invites, removes, and bans are unaffected.</string>
<string name="settings_show_avatar_display_name_changes_messages">Show account events</string>
@ -1075,12 +1065,12 @@ @@ -1075,12 +1065,12 @@
<!-- analytics -->
<string name="settings_analytics">Analytics</string>
<string name="settings_opt_in_of_analytics">Send analytics data</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_opt_in_of_analytics_summary">ElementX collects anonymous analytics to allow us to improve the application.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_opt_in_of_analytics_summary">${app_name} collects anonymous analytics to allow us to improve the application.</string>
<string name="analytics_opt_in_title">Help improve ElementX</string>
<string name="analytics_opt_in_title">Help improve ${app_name}</string>
<!-- The template will be replaced by the value of the resource analytics_opt_in_content_link -->
<string name="analytics_opt_in_content">Help us identify issues and improve ElementX by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.\n\nYou can read all our terms %s.</string>
<string name="analytics_opt_in_content">Help us identify issues and improve ${app_name} by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.\n\nYou can read all our terms %s.</string>
<string name="analytics_opt_in_content_link">here</string>
<string name="analytics_opt_in_list_item_1">We <b>don\'t</b> record or profile any account data</string>
<string name="analytics_opt_in_list_item_2">We <b>don\'t</b> share information with third parties</string>
@ -1099,7 +1089,7 @@ @@ -1099,7 +1089,7 @@
<string name="settings_integration_allow">Allow integrations</string>
<string name="settings_integration_manager">Integration manager</string>
<string name="legals_application_title">ElementX policy</string>
<string name="legals_application_title">${app_name} policy</string>
<string name="legals_home_server_title">Your homeserver policy</string>
<string name="legals_identity_server_title">Your identity server policy</string>
<string name="legals_third_party_notices">Third party libraries</string>
@ -1520,8 +1510,8 @@ @@ -1520,8 +1510,8 @@
<!-- Key Backup -->
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="keys_backup_passphrase_not_empty_error_message">Please delete the passphrase if you want ElementX to generate a recovery key.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="keys_backup_passphrase_not_empty_error_message">Please delete the passphrase if you want ${app_name} to generate a recovery key.</string>
<string name="keys_backup_setup_step1_title">Never lose encrypted messages</string>
<string name="keys_backup_setup_step1_description">Messages in encrypted rooms are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.\n\nSecurely back up your keys to avoid losing them.</string>
@ -1658,7 +1648,10 @@ @@ -1658,7 +1648,10 @@
<string name="error_user_already_logged_in">It looks like you’re trying to connect to another homeserver. Do you want to sign out?</string>
<string name="edit">Edit</string>
<string name="editing">Editing</string>
<string name="reply">Reply</string>
<string name="replying_to">Replying to %s</string>
<string name="quoting">Quoting</string>
<string name="reply_in_thread">Reply in thread</string>
<string name="view_in_room">View In Room</string>
@ -1695,7 +1688,8 @@ @@ -1695,7 +1688,8 @@
<string name="create_new_room">Create New Room</string>
<string name="create_new_space">Create New Space</string>
<string name="error_no_network">No network. Please check your Internet connection.</string>
<string name="error_check_network">Something went wrong. Please check your network connection and try again.</string>
<!-- TODO delete -->
<string name="error_check_network" tools:ignore="UnusedResources">Something went wrong. Please check your network connection and try again.</string>
<string name="change_room_directory_network">"Change network"</string>
<string name="please_wait">"Please wait…"</string>
<string name="updating_your_data">Updating your data…</string>
@ -1751,7 +1745,7 @@ @@ -1751,7 +1745,7 @@
<string name="preference_help">Help</string>
<string name="preference_help_title">Help and support</string>
<string name="preference_help_summary">Get help with using ElementX</string>
<string name="preference_help_summary">Get help with using ${app_name}</string>
<string name="preference_versions">Versions</string>
<string name="preference_system_settings">System settings</string>
@ -1980,8 +1974,8 @@ @@ -1980,8 +1974,8 @@
<string name="ftue_auth_carousel_secure_body">Secure and independent communication that gives you the same level of privacy as a face-to-face conversation in your own home.</string>
<string name="ftue_auth_carousel_control_body">Choose where your conversations are kept, giving you control and independence. Connected via Matrix.</string>
<string name="ftue_auth_carousel_encrypted_body">End-to-end encrypted and no phone number required. No ads or datamining.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="ftue_auth_carousel_workplace_body">ElementX is also great for the workplace. It’s trusted by the world’s most secure organisations.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="ftue_auth_carousel_workplace_body">${app_name} is also great for the workplace. It’s trusted by the world’s most secure organisations.</string>
<string name="ftue_auth_use_case_title">Who will you chat to the most?</string>
<string name="ftue_auth_use_case_subtitle">We\'ll help you get connected</string>
@ -2230,8 +2224,8 @@ @@ -2230,8 +2224,8 @@
<string name="soft_logout_clear_data_dialog_title">Clear data</string>
<string name="soft_logout_clear_data_dialog_content">Clear all data currently stored on this device?\nSign in again to access your account data and messages.</string>
<string name="soft_logout_clear_data_dialog_e2e_warning_content">You’ll lose access to secure messages unless you sign in to recover your encryption keys.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="soft_logout_sso_not_same_user_error">The current session is for user %1$s and you provide credentials for user %2$s. This is not supported by ElementX.\nPlease first clear data, then sign in again on another account.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="soft_logout_sso_not_same_user_error">The current session is for user %1$s and you provide credentials for user %2$s. This is not supported by ${app_name}.\nPlease first clear data, then sign in again on another account.</string>
<string name="permalink_malformed">Your matrix.to link was malformed</string>
<string name="permalink_unsupported_groups">Cannot open this link: communities have been replaced by spaces</string>
@ -2253,8 +2247,8 @@ @@ -2253,8 +2247,8 @@
<string name="autocomplete_limited_results">Showing only the first results, type more letters…</string>
<string name="settings_developer_mode_fail_fast_title">Fail-fast</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_developer_mode_fail_fast_summary">ElementX may crash more often when an unexpected error occurs</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_developer_mode_fail_fast_summary">${app_name} may crash more often when an unexpected error occurs</string>
<string name="settings_developer_mode_show_info_on_screen_title">Show debug info on screen</string>
<string name="settings_developer_mode_show_info_on_screen_summary">Show some useful info to help debugging the application</string>
@ -2362,10 +2356,10 @@ @@ -2362,10 +2356,10 @@
<string name="room_member_open_or_create_dm">Direct message</string>
<string name="room_member_jump_to_read_receipt">Jump to read receipt</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="rendering_event_error_type_of_event_not_handled">ElementX does not handle events of type \'%1$s\'</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="rendering_event_error_exception">ElementX encountered an issue when rendering content of event with id \'%1$s\'</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="rendering_event_error_type_of_event_not_handled">${app_name} does not handle events of type \'%1$s\'</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="rendering_event_error_exception">${app_name} encountered an issue when rendering content of event with id \'%1$s\'</string>
<string name="unignore">Unignore</string>
@ -2491,12 +2485,15 @@ @@ -2491,12 +2485,15 @@
<string name="keys_backup_restore_success_title_already_up_to_date">Keys are already up to date!</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="login_default_session_public_name">ElementX Android</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="login_default_session_public_name">${app_name} Android</string>
<string name="settings_key_requests">Key Requests</string>
<string name="settings_export_trail">Export Audit</string>
<string name="settings_nightly_build">Nightly build</string>
<string name="settings_nightly_build_update">Get the latest build (note: you may have trouble to sign in)</string>
<string name="e2e_use_keybackup">Unlock encrypted messages history</string>
<string name="refresh">Refresh</string>
@ -2623,15 +2620,15 @@ @@ -2623,15 +2620,15 @@
<string name="error_saving_media_file">Could not save media file</string>
<string name="change_password_summary">Set a new account password…</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="use_other_session_content_description">Use the latest ElementX on your other devices, ElementX Web, ElementX Desktop, ElementX iOS, ElementX for Android, or another cross-signing capable Matrix client</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="app_desktop_web">ElementX Web\nElementX Desktop</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="app_ios_android">ElementX iOS\nElementX Android</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="use_other_session_content_description">Use the latest ${app_name} on your other devices, ${app_name} Web, ${app_name} Desktop, ${app_name} iOS, ${app_name} for Android, or another cross-signing capable Matrix client</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="app_desktop_web">${app_name} Web\n${app_name} Desktop</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="app_ios_android">${app_name} iOS\n${app_name} Android</string>
<string name="or_other_mx_capable_client">or another cross-signing capable Matrix client</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="use_latest_app">Use the latest ElementX on your other devices:</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="use_latest_app">Use the latest ${app_name} on your other devices:</string>
<string name="command_description_discard_session">Forces the current outbound group session in an encrypted room to be discarded</string>
<string name="command_description_discard_session_not_handled">Only supported in encrypted rooms</string>
<!-- first will be replaced by recovery_passphrase, second will be replaced by recovery_key-->
@ -2659,8 +2656,12 @@ @@ -2659,8 +2656,12 @@
<string name="unencrypted">Unencrypted</string>
<string name="encrypted_unverified">Encrypted by an unverified device</string>
<string name="key_authenticity_not_guaranteed">The authenticity of this encrypted message can\'t be guaranteed on this device.</string>
<string name="review_logins">Review where you’re logged in</string>
<string name="verify_other_sessions">Verify all your sessions to ensure your account &amp; messages are safe</string>
<!-- TODO TO BE REMOVED -->
<string name="review_logins" tools:ignore="UnusedResources">Review where you’re logged in</string>
<!-- TODO TO BE REMOVED -->
<string name="verify_other_sessions" tools:ignore="UnusedResources">Verify all your sessions to ensure your account &amp; messages are safe</string>
<string name="review_unverified_sessions_title">You have unverified sessions</string>
<string name="review_unverified_sessions_description">Review to ensure your account is safe</string>
<!-- Argument will be replaced by the other session name (e.g, Desktop, mobile) -->
<string name="verify_this_session">Verify the new login accessing your account: %1$s</string>
@ -2686,10 +2687,10 @@ @@ -2686,10 +2687,10 @@
<string name="inviting_users_to_room">Inviting users…</string>
<string name="invite_users_to_room_title">Invite Users</string>
<string name="invite_friends">Invite friends</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="invite_friends_text">Hey, talk to me on ElementX: %s</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="invite_friends_rich_title">🔐 Join me on ElementX</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="invite_friends_text">Hey, talk to me on ${app_name}: %s</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="invite_friends_rich_title">🔐 Join me on ${app_name}</string>
<string name="invitation_sent_to_one_user">Invitation sent to %1$s</string>
<string name="invitations_sent_to_two_users">Invitations sent to %1$s and %2$s</string>
<string name="not_a_valid_qr_code">"It's not a valid matrix QR code"</string>
@ -2710,13 +2711,13 @@ @@ -2710,13 +2711,13 @@
<string name="open_terms_of">Open terms of %s</string>
<string name="disconnect_identity_server_dialog_content">Disconnect from the identity server %s?</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="identity_server_error_outdated_identity_server">This identity server is outdated. ElementX support only API V2.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="identity_server_error_outdated_identity_server">This identity server is outdated. ${app_name} support only API V2.</string>
<string name="identity_server_error_outdated_home_server">This operation is not possible. The homeserver is outdated.</string>
<string name="identity_server_error_no_identity_server_configured">Please first configure an identity server.</string>
<string name="identity_server_error_terms_not_signed">Please first accepts the terms of the identity server in the settings.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="identity_server_error_bulk_sha256_not_supported">For your privacy, ElementX only supports sending hashed user email addresses and phone numbers.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="identity_server_error_bulk_sha256_not_supported">For your privacy, ${app_name} only supports sending hashed user email addresses and phone numbers.</string>
<string name="identity_server_error_binding_error">The association has failed.</string>
<string name="identity_server_error_no_current_binding_error">There is no current association with this identifier.</string>
<string name="identity_server_user_consent_not_provided">The user consent has not been provided.</string>
@ -2810,17 +2811,17 @@ @@ -2810,17 +2811,17 @@
<string name="settings_security_pin_code_summary">If you want to reset your PIN, tap Forgot PIN to logout and reset.</string>
<string name="settings_security_pin_code_use_biometrics_title">Enable biometrics</string>
<string name="settings_security_pin_code_use_biometrics_summary_on">Enable device specific biometrics, like fingerprints and face recognition.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_security_pin_code_use_biometrics_summary_off">PIN code is the only way to unlock ElementX.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_security_pin_code_use_biometrics_summary_off">PIN code is the only way to unlock ${app_name}.</string>
<string name="settings_security_pin_code_use_biometrics_error">Could not enable biometric authentication.</string>
<string name="settings_security_pin_code_notifications_title">Show content in notifications</string>
<string name="settings_security_pin_code_notifications_summary_on">Show details like room names and message content.</string>
<string name="settings_security_pin_code_notifications_summary_off">Only display number of unread messages in a simple notification.</string>
<string name="settings_security_pin_code_grace_period_title">Require PIN after 2 minutes</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_security_pin_code_grace_period_summary_on">PIN code is required after 2 minutes of not using ElementX.</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="settings_security_pin_code_grace_period_summary_off">PIN code is required every time you open ElementX.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_security_pin_code_grace_period_summary_on">PIN code is required after 2 minutes of not using ${app_name}.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="settings_security_pin_code_grace_period_summary_off">PIN code is required every time you open ${app_name}.</string>
<string name="settings_security_pin_code_change_pin_title">Change PIN</string>
<string name="settings_security_pin_code_change_pin_summary">Change your current PIN</string>
<string name="error_opening_banned_room">Can\'t open a room where you are banned from.</string>
@ -2879,8 +2880,8 @@ @@ -2879,8 +2880,8 @@
<string name="call_slide_to_end_conference">Slide to end the call</string>
<string name="re_authentication_activity_title">Re-Authentication Needed</string>
<!-- Note to translators: the translation MUST contain the string "ElementX", which will be replaced by the application name -->
<string name="re_authentication_default_confirm_text">ElementX requires you to enter your credentials to perform this action.</string>
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
<string name="re_authentication_default_confirm_text">${app_name} requires you to enter your credentials to perform this action.</string>
<string name="authentication_error">Failed to authenticate</string>
<string name="a11y_screenshot">Screenshot</string>
@ -3035,7 +3036,7 @@ @@ -3035,7 +3036,7 @@
<string name="labs_auto_report_uisi">Auto Report Decryption Errors.</string>
<string name="labs_auto_report_uisi_desc">Your system will automatically send logs when an unable to decrypt error occurs</string>
<string name="labs_enable_thread_messages">Enable Thread Messages</string>
<string name="labs_enable_thread_messages">Enable threaded messages</string>
<string name="labs_enable_thread_messages_desc">Note: app will be restarted</string>
<string name="settings_show_latest_profile">Show latest user info</string>
<string name="settings_show_latest_profile_description">Show the latest profile info (avatar and display name) for all the messages.</string>
@ -3104,18 +3105,24 @@ @@ -3104,18 +3105,24 @@
<string name="audio_message_file_size">(%1$s)</string>
<string name="voice_broadcast_live">Live</string>
<string name="voice_broadcast_live_broadcast">Live broadcast</string>
<!-- TODO Rename id to voice_broadcast_buffering -->
<string name="a11y_voice_broadcast_buffering">Buffering…</string>
<string name="a11y_resume_voice_broadcast_record">Resume voice broadcast record</string>
<string name="a11y_pause_voice_broadcast_record">Pause voice broadcast record</string>
<string name="a11y_stop_voice_broadcast_record">Stop voice broadcast record</string>
<string name="a11y_play_voice_broadcast">Play or resume voice broadcast</string>
<string name="a11y_pause_voice_broadcast">Pause voice broadcast</string>
<string name="a11y_voice_broadcast_buffering">Buffering</string>
<string name="a11y_voice_broadcast_fast_backward">Fast backward 30 seconds</string>
<string name="a11y_voice_broadcast_fast_forward">Fast forward 30 seconds</string>
<string name="error_voice_broadcast_unauthorized_title">Can’t start a new voice broadcast</string>
<string name="error_voice_broadcast_permission_denied_message">You don’t have the required permissions to start a voice broadcast in this room. Contact a room administrator to upgrade your permissions.</string>
<string name="error_voice_broadcast_blocked_by_someone_else_message">Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.</string>
<string name="error_voice_broadcast_already_in_progress_message">You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.</string>
<!-- Examples of usage: 6h 15min 30sec left / 15min 30sec left / 30sec left -->
<string name="voice_broadcast_recording_time_left">%1$s left</string>
<string name="stop_voice_broadcast_dialog_title">Stop live broadcasting?</string>
<string name="stop_voice_broadcast_content">Are you sure you want to stop your live broadcast? This will end the broadcast and the full recording will be available in the room.</string>
<string name="upgrade_room_for_restricted">Anyone in %s will be able to find and join this room - no need to manually invite everyone. You’ll be able to change this in room settings anytime.</string>
<string name="upgrade_room_for_restricted_no_param">Anyone in a parent space will be able to find and join this room - no need to manually invite everyone. You’ll be able to change this in room settings anytime.</string>
@ -3129,7 +3136,7 @@ @@ -3129,7 +3136,7 @@
<string name="link_this_email_settings_link">Link this email address with your account</string>
<!-- %s will be replaced by the value of link_this_email_settings_link and styled as a link -->
<string name="link_this_email_with_your_account">%s in Settings to receive invites directly in ElementX.</string>
<string name="link_this_email_with_your_account">%s in Settings to receive invites directly in ${app_name}.</string>
<string name="labs_enable_latex_maths">Enable LaTeX mathematics</string>
<string name="restart_the_application_to_apply_changes">Restart the application for the change to take effect.</string>
@ -3200,8 +3207,8 @@ @@ -3200,8 +3207,8 @@
<string name="location_share_live_select_duration_option_1">15 minutes</string>
<string name="location_share_live_select_duration_option_2">1 hour</string>
<string name="location_share_live_select_duration_option_3">8 hours</string>
<string name="location_not_available_dialog_title">ElementX could not access your location</string>
<string name="location_not_available_dialog_content">ElementX could not access your location. Please try again later.</string>
<string name="location_not_available_dialog_title">${app_name} could not access your location</string>
<string name="location_not_available_dialog_content">${app_name} could not access your location. Please try again later.</string>
<string name="location_share_external">Open with</string>
<string name="location_timeline_failed_to_load_map">Failed to load map</string>
<string name="location_share_loading_map_error">Unable to load map\nThis home server may not be configured to display maps.</string>
@ -3214,7 +3221,7 @@ @@ -3214,7 +3221,7 @@
<string name="location_share_live_stop">Stop</string>
<!-- Examples of usage: 6h 15min 30sec left/15min 30sec left/30 sec left-->
<string name="location_share_live_remaining_time">%1$s left</string>
<string name="live_location_sharing_notification_title">ElementX Live Location</string>
<string name="live_location_sharing_notification_title">${app_name} Live Location</string>
<string name="live_location_sharing_notification_description">Location sharing is in progress</string>
<string name="labs_enable_live_location">Enable Live Location Sharing</string>
<string name="labs_enable_live_location_summary">Temporary implementation: locations persist in room history</string>
@ -3257,7 +3264,7 @@ @@ -3257,7 +3264,7 @@
<string name="room_message_autocomplete_notification">Room notification</string>
<!-- Screen sharing -->
<string name="screen_sharing_notification_title">ElementX Screen Sharing</string>
<string name="screen_sharing_notification_title">${app_name} Screen Sharing</string>
<string name="screen_sharing_notification_description">Screen sharing is in progress</string>
<string name="unifiedpush_getdistributors_dialog_title">Choose how to receive notifications</string>
@ -3308,6 +3315,7 @@ @@ -3308,6 +3315,7 @@
<string name="device_manager_verification_status_detail_current_session_unverified">Verify your current session for enhanced secure messaging.</string>
<string name="device_manager_verification_status_detail_other_session_unverified">Verify or sign out from this session for best security and reliability.</string>
<string name="device_manager_verification_status_detail_other_session_unknown">Verify your current session to reveal this session\'s verification status.</string>
<string name="device_manager_verification_status_detail_session_encryption_not_supported">This session doesn\'t support encryption and thus can\'t be verified.</string>
<string name="device_manager_verify_session">Verify Session</string>
<string name="device_manager_view_details">View Details</string>
<string name="device_manager_other_sessions_view_all">View All (%1$d)</string>
@ -3330,7 +3338,7 @@ @@ -3330,7 +3338,7 @@
<item quantity="one">Consider signing out from old sessions (%1$d day or more) that you don’t use anymore.</item>
<item quantity="other">Consider signing out from old sessions (%1$d days or more) that you don’t use anymore.</item>
</plurals>
<string name="device_manager_current_session_title">Current Session</string>
<string name="device_manager_current_session_title">Current session</string>
<string name="device_manager_session_title">Session</string>
<string name="device_manager_device_title">Device</string>
<!-- Examples: Last activity Yesterday at 6PM, Last activity Aug 31 at 5:47PM -->
@ -3361,6 +3369,14 @@ @@ -3361,6 +3369,14 @@
<string name="device_manager_other_sessions_no_inactive_sessions_found">No inactive sessions found.</string>
<string name="device_manager_other_sessions_clear_filter">Clear Filter</string>
<string name="device_manager_other_sessions_select">Select sessions</string>
<string name="device_manager_other_sessions_multi_signout_selection">Sign out</string>
<plurals name="device_manager_other_sessions_multi_signout_all">
<item quantity="one">Sign out of %1$d session</item>
<item quantity="other">Sign out of %1$d sessions</item>
</plurals>
<string name="device_manager_signout_all_other_sessions">Sign out of all other sessions</string>
<string name="device_manager_other_sessions_show_ip_address">Show IP address</string>
<string name="device_manager_other_sessions_hide_ip_address">Hide IP address</string>
<string name="device_manager_session_overview_signout">Sign out of this session</string>
<string name="device_manager_session_details_title">Session details</string>
<string name="device_manager_session_details_description">Application, device, and activity information.</string>
@ -3389,7 +3405,10 @@ @@ -3389,7 +3405,10 @@
<string name="device_manager_learn_more_sessions_unverified_title">Unverified sessions</string>
<string name="device_manager_learn_more_sessions_unverified">Unverified sessions are sessions that have logged in with your credentials but not been cross-verified.\n\nYou should make especially certain that you recognise these sessions as they could represent an unauthorised use of your account.</string>
<string name="device_manager_learn_more_sessions_verified_title">Verified sessions</string>
<string name="device_manager_learn_more_sessions_verified">Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.\n\nThis means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.</string>
<!-- TODO TO BE REMOVED -->
<string name="device_manager_learn_more_sessions_verified" tools:ignore="UnusedResources">Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.\n\nThis means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.</string>
<string name="device_manager_learn_more_sessions_verified_description">Verified sessions are anywhere you are using this account after entering your passphrase or confirming your identity with another verified session.\n\nThis means that you have all the keys needed to unlock your encrypted messages and confirm to other users that you trust this session.</string>
<string name="device_manager_learn_more_sessions_encryption_not_supported">This session doesn\'t support encryption, so it can\'t be verified.\n\nYou won\'t be able to participate in rooms where encryption is enabled when using this session.\n\nFor best security and privacy, it is recommended to use Matrix clients that support encryption.</string>
<string name="device_manager_learn_more_session_rename_title">Renaming sessions</string>
<string name="device_manager_learn_more_session_rename">Other users in direct messages and rooms that you join are able to view a full list of your sessions.\n\nThis provides them with confidence that they are really speaking to you, but it also means they can see the session name you enter here.</string>
<string name="labs_enable_session_manager_title">Enable new session manager</string>
@ -3404,14 +3423,14 @@ @@ -3404,14 +3423,14 @@
<!-- Note to translators: for RTL languages, Spaces will be at the bottom left. Please translate "bottom-left" instead of "bottom-right". Thanks!-->
<string name="home_empty_space_no_rooms_message">Spaces are a new way to group rooms and people. Add an existing room, or create a new one, using the bottom-right button.</string>
<!-- Note to translators: %s will be replaces with current user displayname -->
<string name="home_empty_no_rooms_title">Welcome to ElementX,\n%s.</string>
<string name="home_empty_no_rooms_title">Welcome to ${app_name},\n%s.</string>
<string name="home_empty_no_rooms_message">The all-in-one secure chat app for teams, friends and organisations. Create a chat, or join an existing room, to get started.</string>
<string name="home_empty_no_unreads_title">Nothing to report.</string>
<string name="home_empty_no_unreads_message">This is where your unread messages will show up, when you have some.</string>
<string name="onboarding_new_app_layout_welcome_title">Welcome to a new view!</string>
<!-- Note to translators: for RTL languages, menu will be at the bottom left. Please translate "bottom-left" instead of "bottom-right". Thanks!-->
<string name="onboarding_new_app_layout_welcome_message">To simplify your ElementX, tabs are now optional. Manage them using the top-right menu.</string>
<string name="onboarding_new_app_layout_welcome_message">To simplify your ${app_name}, tabs are now optional. Manage them using the top-right menu.</string>
<string name="onboarding_new_app_layout_spaces_title">Access Spaces</string>
<!-- Note to translators: for RTL languages, Spaces will be at the bottom left. Please translate "bottom-left" instead of "bottom-right". Thanks!-->
<string name="onboarding_new_app_layout_spaces_message">Access your Spaces (bottom-right) faster and easier than ever before.</string>
@ -3460,11 +3479,26 @@ @@ -3460,11 +3479,26 @@
<string name="qr_code_login_confirm_security_code">Confirm</string>
<string name="qr_code_login_confirm_security_code_description">Please ensure that you know the origin of this code. By linking devices, you will provide someone with full access to your account.</string>
<!-- WYSIWYG Composer -->
<!-- Rich text editor -->
<string name="rich_text_editor_format_bold">Apply bold format</string>
<string name="rich_text_editor_format_italic">Apply italic format</string>
<string name="rich_text_editor_format_strikethrough">Apply strikethrough format</string>
<string name="rich_text_editor_format_underline">Apply underline format</string>
<string name="rich_text_editor_link">Set link</string>
<string name="rich_text_editor_full_screen_toggle">Toggle full screen mode</string>
<string name="set_link_text">Text</string>
<string name="set_link_link">Link</string>
<string name="set_link_create">Create a link</string>
<string name="set_link_edit">Edit link</string>
<!-- ReplyTo events -->
<string name="message_reply_to_prefix">In reply to</string>
<string name="message_reply_to_sender_sent_file">sent a file.</string>
<string name="message_reply_to_sender_sent_audio_file">sent an audio file.</string>
<string name="message_reply_to_sender_sent_voice_message">sent a voice message.</string>
<string name="message_reply_to_sender_sent_image">sent an image.</string>
<string name="message_reply_to_sender_sent_video">sent a video.</string>
<string name="message_reply_to_sender_sent_sticker">sent a sticker.</string>
<string name="message_reply_to_sender_created_poll">created a poll.</string>
</resources>

23
libraries/ui-strings/src/main/res/values/strings_no_weblate.xml

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- This file contains string that I do not want to be translated by Weblate translators. -->
<!-- use to retrieve the supported languages list -->
<!-- should the same value as the file name -->
<string name="resources_language">en</string>
<string name="resources_country_code">US</string>
<!-- Value MUST have 4 letters and MUST be in this list: https://www.unicode.org/iso15924/iso15924-codes.html. Example: "Arab", "Cyrl", "Latn", etc. -->
<string name="resources_script">Latn</string>
<string name="lockscreen_num_0">0</string>
<string name="lockscreen_num_1">1</string>
<string name="lockscreen_num_2">2</string>
<string name="lockscreen_num_3">3</string>
<string name="lockscreen_num_4">4</string>
<string name="lockscreen_num_5">5</string>
<string name="lockscreen_num_6">6</string>
<string name="lockscreen_num_7">7</string>
<string name="lockscreen_num_8">8</string>
<string name="lockscreen_num_9">9</string>
</resources>

1
settings.gradle.kts

@ -40,6 +40,7 @@ include(":libraries:matrix") @@ -40,6 +40,7 @@ include(":libraries:matrix")
include(":libraries:matrixui")
include(":libraries:textcomposer")
include(":libraries:elementresources")
include(":libraries:ui-strings")
include(":features:onboarding")
include(":features:login")
include(":features:logout")

57
tools/strings/importStringsFromElement.sh

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
#!/usr/bin/env bash
#
# Copyright (c) 2023 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
printf "\n"
printf "================================================================================\n"
printf "| Importing strings from Element |\n"
printf "================================================================================\n"
basedir=`pwd`
tmpPath="${basedir}/tmpStrings"
## Delete tmp dir
#rm -rf ${tmpPath}
# Create tmp dir
mkdir ${tmpPath}
printf "\n================================================================================\n"
printf "Downloading Element Android source from develop...\n"
curl https://github.com/vector-im/element-android/archive/refs/heads/develop.zip -i -L -o ${tmpPath}/element.zip
printf "\n================================================================================\n"
printf "Unzipping Element Android source...\n"
unzip -q ${tmpPath}/element.zip -d ${tmpPath}
printf "\n================================================================================\n"
printf "Importing the strings...\n"
elementAndroidPath="${tmpPath}/element-android-develop"
cp -R ${elementAndroidPath}/library/ui-strings/src/main/res ${basedir}/libraries/ui-strings/src/main
## Delete tmp dir
rm -rf ${tmpPath}
# Commit all changes to git
# git commit -a -m "Import strings from Element Android"
printf "\n================================================================================\n"
printf "Done\n"
printf "================================================================================\n"
Loading…
Cancel
Save