Merge branch 'release/25.03.2' into main

This commit is contained in:
ganfra 2025-03-21 15:03:59 +01:00
commit bee248e2d5
942 changed files with 9103 additions and 3525 deletions

View file

@ -1,17 +0,0 @@
name: Prevent blocked
on:
pull_request:
types: [opened, labeled, unlabeled]
jobs:
prevent-blocked:
name: Prevent blocked
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- name: Add notice
uses: actions/github-script@v7
if: contains(github.event.pull_request.labels.*.name, 'X-Blocked')
with:
script: |
core.setFailed("PR has been labeled with X-Blocked; it cannot be merged.");

View file

@ -65,7 +65,7 @@ jobs:
retention-days: 5
overwrite: true
if-no-files-found: error
- uses: rnkdsh/action-upload-diawi@v1.5.6
- uses: rnkdsh/action-upload-diawi@v1.5.7
id: diawi
# Do not fail the whole build if Diawi upload fails
continue-on-error: true
@ -89,7 +89,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Compile release sources
if: ${{ matrix.variant == 'release' }}
run: ./gradlew compileReleaseSources -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES
run: ./gradlew bundleGplayRelease -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES
- name: Compile nightly sources
if: ${{ matrix.variant == 'nightly' }}
run: ./gradlew compileGplayNightlySources -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES

View file

@ -33,7 +33,7 @@ jobs:
# https://github.com/actions/checkout/issues/881
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
- name: Clone submodules

View file

@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
- name: Clone submodules

View file

@ -18,7 +18,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
- name: Clone submodules

77
.github/workflows/pull_request.yml vendored Normal file
View file

@ -0,0 +1,77 @@
name: Pull Request
on:
pull_request:
types: [ opened, edited, labeled, unlabeled, synchronize ]
workflow_call:
secrets:
ELEMENT_BOT_TOKEN:
required: true
jobs:
prevent-blocked:
name: Prevent blocked
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- name: Add notice
uses: actions/github-script@v7
if: contains(github.event.pull_request.labels.*.name, 'X-Blocked')
with:
script: |
core.setFailed("PR has been labeled with X-Blocked; it cannot be merged.");
community-prs:
name: Label Community PRs
runs-on: ubuntu-latest
if: github.event.action == 'opened'
permissions:
pull-requests: write
steps:
- name: Check membership
if: github.event.pull_request.user.login != 'renovate[bot]'
uses: tspascoal/get-user-teams-membership@57e9f42acd78f4d0f496b3be4368fc5f62696662 # v3
id: teams
with:
username: ${{ github.event.pull_request.user.login }}
organization: element-hq
team: Vector Core
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN_READ_ORG }}
- name: Add label
if: steps.teams.outputs.isTeamMember == 'false'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['Z-Community-PR']
});
close-if-fork-develop:
name: Forbid develop branch fork contributions
runs-on: ubuntu-latest
if: >
github.event.action == 'opened' &&
github.event.pull_request.head.ref == 'develop' &&
github.event.pull_request.head.repo.full_name != github.repository
steps:
- name: Close pull request
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: "Thanks for opening this pull request, unfortunately we do not accept contributions from the main" +
" branch of your fork, please re-open once you switch to an alternative branch for everyone's sanity.",
});
github.rest.pulls.update({
pull_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
state: 'closed'
});

View file

@ -19,7 +19,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
@ -77,7 +77,7 @@ jobs:
# https://github.com/actions/checkout/issues/881
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
@ -117,7 +117,7 @@ jobs:
# https://github.com/actions/checkout/issues/881
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
@ -161,7 +161,7 @@ jobs:
# https://github.com/actions/checkout/issues/881
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
@ -201,7 +201,7 @@ jobs:
# https://github.com/actions/checkout/issues/881
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}
@ -241,7 +241,7 @@ jobs:
# https://github.com/actions/checkout/issues/881
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}

View file

@ -50,7 +50,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}

View file

@ -39,7 +39,7 @@ jobs:
# https://github.com/actions/checkout/issues/881
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
- name: Add SSH private keys for submodule repositories
uses: webfactory/ssh-agent@v0.9.0
uses: webfactory/ssh-agent@v0.9.1
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }}
with:
ssh-private-key: ${{ secrets.ELEMENT_ENTERPRISE_DEPLOY_KEY }}

1
.gitignore vendored
View file

@ -43,6 +43,7 @@ captures/
.idea/.name
.idea/androidTestResultsUserPreferences.xml
.idea/assetWizardSettings.xml
.idea/AndroidProjectSystem.xml
.idea/compiler.xml
.idea/deploymentTargetDropDown.xml
.idea/deploymentTargetSelector.xml

View file

@ -1,3 +1,43 @@
Changes in Element X v25.03.1
=============================
<!-- Release notes generated using configuration in .github/release.yml at v25.03.1 -->
## What's Changed
### ✨ Features
* Enable the Event cache by default. by @bmarty in https://github.com/element-hq/element-x-android/pull/4373
### 🙌 Improvements
* change(create room) : use history visibility "invited" by @ganfra in https://github.com/element-hq/element-x-android/pull/4335
* change(room directory) : move the the room directory entry by @ganfra in https://github.com/element-hq/element-x-android/pull/4348
* [Change] Invited state room preview by @ganfra in https://github.com/element-hq/element-x-android/pull/4353
* change(left room snackbar) : manage cancel knock and decline invite by @ganfra in https://github.com/element-hq/element-x-android/pull/4360
### 🐛 Bugfixes
* Restore manual `Client` cleanup on session logout by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4333
### 🗣 Translations
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/4346
### 🧱 Build
* Fix typo on job name. by @bmarty in https://github.com/element-hq/element-x-android/pull/4352
### Dependency upgrades
* chore(deps): update plugin ktlint to v12.2.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4338
* fix(deps): update dependency org.maplibre.gl:android-sdk to v11.8.2 by @renovate in https://github.com/element-hq/element-x-android/pull/4340
* fix(deps): update dependency io.mockk:mockk to v1.13.17 by @renovate in https://github.com/element-hq/element-x-android/pull/4334
* fix(deps): update kotlin to v2.1.10-1.0.31 by @renovate in https://github.com/element-hq/element-x-android/pull/4337
* fix(deps): update dependency com.google.firebase:firebase-bom to v33.10.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4339
* Migrate to coil3 by @bmarty in https://github.com/element-hq/element-x-android/pull/4347
* fix(deps): update dependency org.jsoup:jsoup to v1.19.1 by @renovate in https://github.com/element-hq/element-x-android/pull/4351
* deps(rust sdk) : update to 25.03.05 by @ganfra in https://github.com/element-hq/element-x-android/pull/4370
* Update dependency org.matrix.rustcomponents:sdk-android to v25.3.6 by @renovate in https://github.com/element-hq/element-x-android/pull/4371
### Others
* Prevent PRs with the X-Blocked label from being merged by @robintown in https://github.com/element-hq/element-x-android/pull/4350
* Fix some icon colors by @bmarty in https://github.com/element-hq/element-x-android/pull/4365
* Remove PreferenceText, replace by ListItem. by @bmarty in https://github.com/element-hq/element-x-android/pull/4369
* Show error screens in group calls by @robintown in https://github.com/element-hq/element-x-android/pull/4297
## New Contributors
* @robintown made their first contribution in https://github.com/element-hq/element-x-android/pull/4350
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v25.03.0...v25.03.1
Changes in Element X v25.03.0
=============================

View file

@ -10,6 +10,7 @@
import com.android.build.api.variant.FilterConfiguration.FilterType.ABI
import com.android.build.gradle.internal.tasks.factory.dependsOn
import com.android.build.gradle.tasks.GenerateBuildConfig
import com.google.firebase.appdistribution.gradle.firebaseAppDistribution
import config.BuildTimeConfig
import extension.AssetCopyTask
import extension.ComponentMergingStrategy

View file

@ -15,7 +15,7 @@ import io.element.android.x.di.AppComponent
import io.element.android.x.di.DaggerAppComponent
import io.element.android.x.info.logApplicationInfo
import io.element.android.x.initializer.CrashInitializer
import io.element.android.x.initializer.TracingInitializer
import io.element.android.x.initializer.PlatformInitializer
class ElementXApplication : Application(), DaggerComponentOwner {
override val daggerComponent: AppComponent = DaggerAppComponent.factory().create(this)
@ -24,7 +24,7 @@ class ElementXApplication : Application(), DaggerComponentOwner {
super.onCreate()
AppInitializer.getInstance(this).apply {
initializeComponent(CrashInitializer::class.java)
initializeComponent(TracingInitializer::class.java)
initializeComponent(PlatformInitializer::class.java)
initializeComponent(CacheCleanerInitializer::class.java)
}
logApplicationInfo(this)

View file

@ -64,6 +64,7 @@ class MainActivity : NodeActivity() {
ElementThemeApp(
appPreferencesStore = appBindings.preferencesStore(),
enterpriseService = appBindings.enterpriseService(),
buildMeta = appBindings.buildMeta()
) {
CompositionLocalProvider(
LocalSnackbarDispatcher provides appBindings.snackbarDispatcher(),

View file

@ -13,8 +13,11 @@ import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
import io.element.android.features.lockscreen.api.LockScreenService
import io.element.android.features.rageshake.api.reporter.BugReporter
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.matrix.api.platform.InitPlatformService
import io.element.android.libraries.matrix.api.tracing.TracingService
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import io.element.android.services.analytics.api.AnalyticsService
@ -25,6 +28,8 @@ interface AppBindings {
fun tracingService(): TracingService
fun platformService(): InitPlatformService
fun bugReporter(): BugReporter
fun lockScreenService(): LockScreenService
@ -38,4 +43,8 @@ interface AppBindings {
fun analyticsService(): AnalyticsService
fun enterpriseService(): EnterpriseService
fun featureFlagService(): FeatureFlagService
fun buildMeta(): BuildMeta
}

View file

@ -12,9 +12,9 @@ import android.system.Os
import androidx.startup.Initializer
import io.element.android.features.rageshake.api.reporter.BugReporter
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.tracing.TracingConfiguration
import io.element.android.libraries.matrix.api.tracing.WriteToFilesConfiguration
import io.element.android.x.BuildConfig
import io.element.android.x.di.AppBindings
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
@ -22,22 +22,24 @@ import timber.log.Timber
private const val ELEMENT_X_TARGET = "elementx"
class TracingInitializer : Initializer<Unit> {
class PlatformInitializer : Initializer<Unit> {
override fun create(context: Context) {
val appBindings = context.bindings<AppBindings>()
val tracingService = appBindings.tracingService()
val platformService = appBindings.platformService()
val bugReporter = appBindings.bugReporter()
Timber.plant(tracingService.createTimberTree(ELEMENT_X_TARGET))
val preferencesStore = appBindings.preferencesStore()
val featureFlagService = appBindings.featureFlagService()
val logLevel = runBlocking { preferencesStore.getTracingLogLevelFlow().first() }
val tracingConfiguration = TracingConfiguration(
writesToLogcat = BuildConfig.DEBUG,
writesToLogcat = runBlocking { featureFlagService.isFeatureEnabled(FeatureFlags.PrintLogsToLogcat) },
writesToFilesConfiguration = defaultWriteToDiskConfiguration(bugReporter),
logLevel = logLevel,
extraTargets = listOf(ELEMENT_X_TARGET),
)
bugReporter.setCurrentTracingLogLevel(logLevel.name)
tracingService.setupTracing(tracingConfiguration)
platformService.init(tracingConfiguration)
// Also set env variable for rust back trace
Os.setenv("RUST_BACKTRACE", "1", true)
}

View file

@ -9,6 +9,7 @@
<locale android:name="en_US"/>
<locale android:name="es"/>
<locale android:name="et"/>
<locale android:name="eu"/>
<locale android:name="fa"/>
<locale android:name="fi"/>
<locale android:name="fr"/>

View file

@ -73,17 +73,24 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.verification.SessionVerificationRequestDetails
import io.element.android.libraries.matrix.api.verification.SessionVerificationServiceListener
import io.element.android.libraries.matrix.api.verification.VerificationRequest
import io.element.android.services.appnavstate.api.AppNavigationStateService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeout
import kotlinx.parcelize.Parcelize
import timber.log.Timber
import java.time.Duration
import java.time.Instant
import java.util.Optional
import java.util.UUID
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
import kotlin.time.toKotlinDuration
@ContributesNode(SessionScope::class)
class LoggedInFlowNode @AssistedInject constructor(
@ -127,8 +134,35 @@ class LoggedInFlowNode @AssistedInject constructor(
)
private val verificationListener = object : SessionVerificationServiceListener {
override fun onIncomingSessionRequest(sessionVerificationRequestDetails: SessionVerificationRequestDetails) {
backstack.singleTop(NavTarget.IncomingVerificationRequest(sessionVerificationRequestDetails))
override fun onIncomingSessionRequest(verificationRequest: VerificationRequest.Incoming) {
// Without this launch the rendering and actual state of this Appyx node's children gets out of sync, resulting in a crash.
// This might be because this method is called back from Rust in a background thread.
lifecycleScope.launch {
val receivedAt = Instant.now()
// Wait until the app is in foreground to display the incoming verification request
appNavigationStateService.appNavigationState.first { it.isInForeground }
// TODO there should also be a timeout for > 10 minutes elapsed since the request was created, but the SDK doesn't expose that info yet
val now = Instant.now()
val elapsedTimeSinceReceived = Duration.between(receivedAt, now).toKotlinDuration()
// Discard the incoming verification request if it has timed out
if (elapsedTimeSinceReceived > 2.minutes) {
Timber.w("Incoming verification request ${verificationRequest.details.flowId} discarded due to timeout.")
return@launch
}
// Wait for the RoomList UI to be ready so the incoming verification screen can be displayed on top of it
// Otherwise, the RoomList UI may be incorrectly displayed on top
withTimeout(5.seconds) {
backstack.elements.first { elements ->
elements.any { it.key.navTarget == NavTarget.RoomList }
}
}
backstack.singleTop(NavTarget.IncomingVerificationRequest(verificationRequest))
}
}
}
@ -218,7 +252,7 @@ class LoggedInFlowNode @AssistedInject constructor(
data object LogoutForNativeSlidingSyncMigrationNeeded : NavTarget
@Parcelize
data class IncomingVerificationRequest(val data: SessionVerificationRequestDetails) : NavTarget
data class IncomingVerificationRequest(val data: VerificationRequest.Incoming) : NavTarget
}
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Cerrar sesión y actualizar"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s ya no es compatible con el antiguo protocolo. Cierra sesión y vuelve a iniciarla para seguir usando la aplicación."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Tu servidor base ya no es compatible con el protocolo anterior. Cierra sesión y vuelve a iniciarla para seguir usando la aplicación."</string>
</resources>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Zure zerbitzaria ez da bateragarria protokolo zaharrarekin. Amaitu saioa eta hasi berriro aplikazioa erabiltzen jarraitzeko."</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Kirjaudu Ulos &amp; Päivitä"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s ei enää tue vanhaa protokollaa. Kirjaudu ulos ja takaisin sisään jatkaaksesi sovelluksen käyttöä."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Kotipalvelimesi ei enää tue vanhaa protokollaa. Kirjaudu ulos ja takaisin sisään jatkaaksesi sovelluksen käyttöä."</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Kijelentkezés és frissítés"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s már nem támogatja a régi protokollt. Kérjük, jelentkezzen ki és jelentkezzen be újra az alkalmazás használatának folytatásához."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"A Matrix-kiszolgáló már nem támogatja a régi protokollt. Az alkalmazás további használatához jelentkezzen ki és be."</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Esci e aggiorna"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s non supporta più il vecchio protocollo. Esci e accedi nuovamente per continuare a utilizzare l\'app."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Il tuo homeserver non supporta più il vecchio protocollo. Esci e rientra per continuare a usare l\'app."</string>
</resources>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Logg ut og oppgrader"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Hjemmeserveren din støtter ikke lenger den gamle protokollen. Vennligst logg ut og inn igjen for å fortsette å bruke appen."</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Wyloguj się i zaktualizuj"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s już nie wspiera starego protokołu. Zaloguj się ponownie, aby dalej korzystać z aplikacji."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Twój serwer domowy już nie wspiera starego protokołu. Zaloguj się ponownie, aby kontynuować korzystanie z aplikacji."</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Sair &amp; Atualizar"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s já não suporta o protocolo antigo. Termina a sessão e volta a iniciar sessão para continuares a utilizar a aplicação."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Seu homeserver não suporta mais o protocolo antigo. Termine sessão e volte a iniciar sessão para continuar a utilizar a aplicação."</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Logga ut och uppgradera"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s stöder inte längre det gamla protokollet. Logga ut och logga in igen för att fortsätta använda appen."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Din hemserver stöder inte längre det gamla protokollet. Logga ut och logga in igen för att fortsätta använda appen."</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Вийти та оновити"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s більше не підтримує старий протокол. Вийдіть і знов увійдіть, щоб продовжити користуватися застосунком."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Ваш домашній сервер більше не підтримує старий протокол. Будь ласка, вийдіть і увійдіть знову, щоб продовжити використання програми."</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"登出並升級"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s 不再支援舊版通訊協定。請登出並重新登入以繼續使用應用程式。"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"您的家伺服器不再支援舊協定。請登出並重新登入以繼續使用應用程式。"</string>
</resources>

@ -1 +1 @@
Subproject commit 6d96bf58aec2ecc77b408858272cd64ec26e10d0
Subproject commit 665a15a1907a116816ffd1653bccfeaeeb7a2968

View file

@ -0,0 +1,2 @@
Main changes in this version: bug fixes and improvements.
Full changelog: https://github.com/element-hq/element-x-android/releases

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_settings_help_us_improve">"Partekatu erabilerari buruzko datu anonimoak arazoak identifikatzen laguntzeko."</string>
<string name="screen_analytics_settings_read_terms">"Gure baldintza guztiak irakur ditzakezu %1$s ."</string>
<string name="screen_analytics_settings_read_terms_content_link">"hemen"</string>
<string name="screen_analytics_settings_share_data">"Partekatu analisi-datuak"</string>
</resources>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_prompt_help_us_improve">"Partekatu erabilerari buruzko datu anonimoak arazoak identifikatzen laguntzeko."</string>
<string name="screen_analytics_prompt_read_terms">"Gure baldintza guztiak irakur ditzakezu %1$s ."</string>
<string name="screen_analytics_prompt_read_terms_content_link">"hemen"</string>
<string name="screen_analytics_prompt_settings">"Edozein unetan desaktibatu dezakezu"</string>
<string name="screen_analytics_prompt_third_party_sharing">"Ez ditugu zure datuak hirugarrenekin partekatuko"</string>
<string name="screen_analytics_prompt_title">"Lagundu %1$s hobetzen"</string>
</resources>

View file

@ -110,7 +110,7 @@ class RingingCallNotificationCreator @Inject constructor(
)
return NotificationCompat.Builder(context, notificationChannelId)
.setSmallIcon(CommonDrawables.ic_notification_small)
.setSmallIcon(CommonDrawables.ic_notification)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setStyle(NotificationCompat.CallStyle.forIncomingCall(caller, declineIntent, answerIntent).setIsVideo(true))

View file

@ -67,7 +67,7 @@ class CallForegroundService : Service() {
val callActivityIntent = Intent(this, ElementCallActivity::class.java)
val pendingIntent = PendingIntentCompat.getActivity(this, 0, callActivityIntent, 0, false)
val notification = NotificationCompat.Builder(this, foregroundServiceChannel.id)
.setSmallIcon(IconCompat.createWithResource(this, CommonDrawables.ic_notification_small))
.setSmallIcon(IconCompat.createWithResource(this, CommonDrawables.ic_notification))
.setContentTitle(getString(R.string.call_foreground_service_title_android))
.setContentText(getString(R.string.call_foreground_service_message_android))
.setContentIntent(pendingIntent)

View file

@ -48,6 +48,7 @@ import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.theme.ElementThemeApp
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import timber.log.Timber
@ -64,6 +65,7 @@ class ElementCallActivity :
@Inject lateinit var appPreferencesStore: AppPreferencesStore
@Inject lateinit var enterpriseService: EnterpriseService
@Inject lateinit var pictureInPicturePresenter: PictureInPicturePresenter
@Inject lateinit var buildMeta: BuildMeta
private lateinit var presenter: Presenter<CallScreenState>
@ -114,6 +116,7 @@ class ElementCallActivity :
ElementThemeApp(
appPreferencesStore = appPreferencesStore,
enterpriseService = enterpriseService,
buildMeta = buildMeta,
) {
val state = presenter.present()
eventSink = state.eventSink

View file

@ -21,6 +21,7 @@ import io.element.android.features.call.impl.utils.ActiveCallManager
import io.element.android.features.call.impl.utils.CallState
import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.theme.ElementThemeApp
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import kotlinx.coroutines.flow.filter
@ -51,6 +52,9 @@ class IncomingCallActivity : AppCompatActivity() {
@Inject
lateinit var enterpriseService: EnterpriseService
@Inject
lateinit var buildMeta: BuildMeta
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -71,6 +75,7 @@ class IncomingCallActivity : AppCompatActivity() {
ElementThemeApp(
appPreferencesStore = appPreferencesStore,
enterpriseService = enterpriseService,
buildMeta = buildMeta,
) {
IncomingCallScreen(
notificationData = notificationData,

View file

@ -38,7 +38,8 @@ class DefaultCallWidgetProvider @Inject constructor(
val baseUrl = appPreferencesStore.getCustomElementCallBaseUrlFlow().firstOrNull()
?: elementCallBaseUrlProvider.provides(matrixClient)
?: ElementCallConfig.DEFAULT_BASE_URL
val widgetSettings = callWidgetSettingsProvider.provide(baseUrl, encrypted = room.isEncrypted)
val isEncrypted = room.info().isEncrypted ?: room.getUpdatedIsEncrypted().getOrThrow()
val widgetSettings = callWidgetSettingsProvider.provide(baseUrl, encrypted = isEncrypted)
val callUrl = room.generateWidgetWebViewUrl(
widgetSettings = widgetSettings,
clientId = clientId,

View file

@ -3,4 +3,5 @@
<string name="call_foreground_service_channel_title_android">"Llamada en curso"</string>
<string name="call_foreground_service_message_android">"Pulsa para regresar a la llamada"</string>
<string name="call_foreground_service_title_android">"☎️ Llamada en curso"</string>
<string name="screen_incoming_call_subtitle_android">"Llamada de Element Call entrante"</string>
</resources>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="call_foreground_service_channel_title_android">"Abian den deia"</string>
<string name="call_foreground_service_message_android">"Sakatu deira itzultzeko."</string>
<string name="call_foreground_service_title_android">"☎️ Deia abian"</string>
<string name="screen_incoming_call_subtitle_android">"Element deia jasotzen"</string>
</resources>

View file

@ -13,5 +13,6 @@
<string name="screen_create_room_room_name_label">"Назва пакоя"</string>
<string name="screen_create_room_title">"Стварыце пакой"</string>
<string name="screen_create_room_topic_label">"Тэма (неабавязкова)"</string>
<string name="screen_room_directory_search_title">"Каталог пакояў"</string>
<string name="screen_start_chat_error_starting_chat">"Пры спробе пачаць чат адбылася памылка"</string>
</resources>

View file

@ -19,6 +19,7 @@ To můžete kdykoli změnit v nastavení místnosti."</string>
<string name="screen_create_room_room_visibility_section_title">"Viditelnost místnosti"</string>
<string name="screen_create_room_title">"Vytvořit místnost"</string>
<string name="screen_create_room_topic_label">"Téma (nepovinné)"</string>
<string name="screen_room_directory_search_title">"Adresář místností"</string>
<string name="screen_start_chat_error_starting_chat">"Při pokusu o zahájení chatu došlo k chybě"</string>
<string name="screen_start_chat_join_room_by_address_action">"Vstoupit do místnosti pomocí adresy"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Neplatná adresa"</string>

View file

@ -19,5 +19,12 @@ Sie können dies aber jederzeit in den Chatroomeinstellungen ändern."</string>
<string name="screen_create_room_room_visibility_section_title">" Sichtbarkeit des Chatrooms"</string>
<string name="screen_create_room_title">"Raum erstellen"</string>
<string name="screen_create_room_topic_label">"Thema (optional)"</string>
<string name="screen_room_directory_search_title">"Raum-Verzeichnis"</string>
<string name="screen_start_chat_error_starting_chat">"Beim Versuch, einen Chat zu starten, ist ein Fehler aufgetreten"</string>
<string name="screen_start_chat_join_room_by_address_action">"Raum per Adresse betreten"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Keine gültige Adresse"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Eintreten…"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Passender Raum gefunden"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Raum nicht gefunden"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"z. B. #room -name:matrix.org"</string>
</resources>

View file

@ -18,5 +18,6 @@
<string name="screen_create_room_room_visibility_section_title">"Ορατότητα δωματίου"</string>
<string name="screen_create_room_title">"Δημιούργησε ένα δωμάτιο"</string>
<string name="screen_create_room_topic_label">"Θέμα (προαιρετικό)"</string>
<string name="screen_room_directory_search_title">"Κατάλογος δωματίων"</string>
<string name="screen_start_chat_error_starting_chat">"Παρουσιάστηκε σφάλμα κατά την προσπάθεια έναρξης μιας συνομιλίας"</string>
</resources>

View file

@ -3,11 +3,24 @@
<string name="screen_create_room_action_create_room">"Nueva sala"</string>
<string name="screen_create_room_add_people_title">"Invitar personas"</string>
<string name="screen_create_room_error_creating_room">"Se ha producido un error al crear la sala"</string>
<string name="screen_create_room_private_option_description">"Los mensajes de esta sala están cifrados. La encriptación no se puede desactivar después."</string>
<string name="screen_create_room_private_option_title">"Sala privada (sólo con invitación)"</string>
<string name="screen_create_room_public_option_description">"Los mensajes no están cifrados y cualquiera puede leerlos. Puedes activar la encriptación más adelante."</string>
<string name="screen_create_room_private_option_description">"Solo las personas invitadas pueden acceder a esta sala. Todos los mensajes están cifrados de extremo a extremo."</string>
<string name="screen_create_room_private_option_title">"Sala privada"</string>
<string name="screen_create_room_public_option_description">"Cualquiera puede encontrar esta sala.
Puedes cambiar esto en cualquier momento en los ajustes de la sala."</string>
<string name="screen_create_room_public_option_title">"Sala pública"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Cualquiera puede unirse a esta sala"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Cualquiera"</string>
<string name="screen_create_room_room_access_section_header">"Acceso a la sala"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Cualquiera puede solicitar unirse a la sala, pero un administrador o un moderador tendrá que aceptar la solicitud"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Solicitud para unirse"</string>
<string name="screen_create_room_room_address_section_footer">"Para que esta sala sea visible en el directorio de salas públicas, necesitarás una dirección de sala."</string>
<string name="screen_create_room_room_address_section_title">"Dirección de la sala"</string>
<string name="screen_create_room_room_name_label">"Nombre de la sala"</string>
<string name="screen_create_room_room_visibility_section_title">"Visibilidad de la sala"</string>
<string name="screen_create_room_title">"Crear una sala"</string>
<string name="screen_create_room_topic_label">"Tema (opcional)"</string>
<string name="screen_room_directory_search_title">"Directorio de salas"</string>
<string name="screen_start_chat_error_starting_chat">"Se ha producido un error al intentar iniciar un chat"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Introducir…"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"p. ej., #nombre-de-la-sala:matrix.org"</string>
</resources>

View file

@ -19,6 +19,7 @@ Sa võid seda jututoa seadistustest alati muuta."</string>
<string name="screen_create_room_room_visibility_section_title">"Jututoa nähtavus"</string>
<string name="screen_create_room_title">"Loo jututuba"</string>
<string name="screen_create_room_topic_label">"Teema (kui soovid lisada)"</string>
<string name="screen_room_directory_search_title">"Jututubade kataloog"</string>
<string name="screen_start_chat_error_starting_chat">"Vestluse alustamisel tekkis viga"</string>
<string name="screen_start_chat_join_room_by_address_action">"Liitu jututoaga aadressi alusel"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"See pole kehtiv aadress"</string>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_create_room_action_create_room">"Gela berria"</string>
<string name="screen_create_room_add_people_title">"Gonbidatu jendea"</string>
<string name="screen_create_room_error_creating_room">"Errorea gertatu da gela sortzean"</string>
<string name="screen_create_room_private_option_description">"Gonbidatutako jendea soilik sar daiteke gelara. Mezu guztiak daude ertzetik ertzera zifratuta."</string>
<string name="screen_create_room_private_option_title">"Gela pribatua"</string>
<string name="screen_create_room_public_option_description">"Edonork aurki dezake gela hau.
Gelaren ezarpenetan aldatu dezakezu hobespena."</string>
<string name="screen_create_room_public_option_title">"Gela publikoa"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Edonor sar daiteke gela honetara"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Edonork"</string>
<string name="screen_create_room_room_access_section_header">"Gelarako sarbidea"</string>
<string name="screen_create_room_room_address_section_title">"Gelaren helbidea"</string>
<string name="screen_create_room_room_name_label">"Gelaren izena"</string>
<string name="screen_create_room_room_visibility_section_title">"Gelaren ikusgarritasuna"</string>
<string name="screen_create_room_title">"Sortu gela"</string>
<string name="screen_create_room_topic_label">"Mintzagaia (aukerakoa)"</string>
<string name="screen_room_directory_search_title">"Gelen direktorioa"</string>
<string name="screen_start_chat_error_starting_chat">"Errorea gertatu da txata hasten saiatzean"</string>
</resources>

View file

@ -10,4 +10,5 @@
<string name="screen_create_room_room_name_label">"نام اتاق"</string>
<string name="screen_create_room_title">"ایجاد اتاق"</string>
<string name="screen_create_room_topic_label">"موضوع (اختیاری)"</string>
<string name="screen_room_directory_search_title">"فهرست اتاق‌ها"</string>
</resources>

View file

@ -19,5 +19,12 @@ Voit muuttaa tämän milloin tahansa huoneen asetuksista."</string>
<string name="screen_create_room_room_visibility_section_title">"Huoneen näkyvyys"</string>
<string name="screen_create_room_title">"Luo huone"</string>
<string name="screen_create_room_topic_label">"Aihe (valinnainen)"</string>
<string name="screen_room_directory_search_title">"Huoneluettelo"</string>
<string name="screen_start_chat_error_starting_chat">"Keskustelun aloituksessa tapahtui virhe"</string>
<string name="screen_start_chat_join_room_by_address_action">"Liity huoneeseen osoitteella"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Osoite ei ole kelvollinen"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Syötä…"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Täsmäävä huone löytyi"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Huonetta ei löytynyt"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"esim. #huoneen-nimi:matrix.org"</string>
</resources>

View file

@ -19,6 +19,7 @@ Vous pouvez modifier cela à tout moment dans les paramètres du salon."</string
<string name="screen_create_room_room_visibility_section_title">"Visibilité du salon"</string>
<string name="screen_create_room_title">"Créer un salon"</string>
<string name="screen_create_room_topic_label">"Sujet (facultatif)"</string>
<string name="screen_room_directory_search_title">"Annuaire des salons"</string>
<string name="screen_start_chat_error_starting_chat">"Une erreur sest produite lors de la tentative de création de la discussion"</string>
<string name="screen_start_chat_join_room_by_address_action">"Saisir une adresse de salon"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Ce nest pas une adresse valide"</string>

View file

@ -19,5 +19,12 @@ Ezt bármikor módosíthatja a szobabeállításokban."</string>
<string name="screen_create_room_room_visibility_section_title">"Szoba láthatósága"</string>
<string name="screen_create_room_title">"Szoba létrehozása"</string>
<string name="screen_create_room_topic_label">"Téma (nem kötelező)"</string>
<string name="screen_room_directory_search_title">"Szobakatalógus"</string>
<string name="screen_start_chat_error_starting_chat">"Hiba történt a csevegés indításakor"</string>
<string name="screen_start_chat_join_room_by_address_action">"Csatlakozás a szobához cím szerint"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Nem érvényes cím"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Írja be…"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Megfelelő szoba található"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Szoba nem található"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"pl. #szoba-neve:matrix.org"</string>
</resources>

View file

@ -18,5 +18,6 @@ Anda dapat mengubah ini kapan pun dalam pengaturan ruangan."</string>
<string name="screen_create_room_room_visibility_section_title">"Keterlihatan ruangan"</string>
<string name="screen_create_room_title">"Buat ruangan"</string>
<string name="screen_create_room_topic_label">"Topik (opsional)"</string>
<string name="screen_room_directory_search_title">"Direktori ruangan"</string>
<string name="screen_start_chat_error_starting_chat">"Terjadi kesalahan saat mencoba memulai obrolan"</string>
</resources>

View file

@ -19,5 +19,12 @@ Puoi modificarlo in qualsiasi momento nelle impostazioni della stanza."</string>
<string name="screen_create_room_room_visibility_section_title">"Visibilità della stanza"</string>
<string name="screen_create_room_title">"Crea una stanza"</string>
<string name="screen_create_room_topic_label">"Argomento (facoltativo)"</string>
<string name="screen_room_directory_search_title">"Elenco delle stanze"</string>
<string name="screen_start_chat_error_starting_chat">"Si è verificato un errore durante il tentativo di avviare una chat"</string>
<string name="screen_start_chat_join_room_by_address_action">"Accedi alla stanza tramite indirizzo"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Indirizzo non valido"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Inserisci…"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Stanza trovata"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Stanza non trovata"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"ad esempio #room -name:matrix.org"</string>
</resources>

View file

@ -10,5 +10,6 @@
<string name="screen_create_room_room_name_label">"ოთახის სახელი"</string>
<string name="screen_create_room_title">"ოთახის შექმნა"</string>
<string name="screen_create_room_topic_label">"თემა (სურვილისამებრ)"</string>
<string name="screen_room_directory_search_title">"ოთახის კატალოგი"</string>
<string name="screen_start_chat_error_starting_chat">"ჩატის დაწყების მცდელობისას შეცდომა მოხდა"</string>
</resources>

View file

@ -8,8 +8,14 @@
<string name="screen_create_room_public_option_description">"Alle kan finne dette rommet.
Du kan endre dette når som helst i rominnstillingene."</string>
<string name="screen_create_room_public_option_title">"Offentlig rom"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Alle kan bli med i dette rommet"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Alle kan be om å få bli med i rommet, men en administrator eller moderator må godta forespørselen"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Be om å bli med"</string>
<string name="screen_create_room_room_address_section_title">"Romadresse"</string>
<string name="screen_create_room_room_name_label">"Romnavn"</string>
<string name="screen_create_room_room_visibility_section_title">"Romsynlighet"</string>
<string name="screen_create_room_title">"Opprett et rom"</string>
<string name="screen_create_room_topic_label">"Emne (valgfritt)"</string>
<string name="screen_room_directory_search_title">"Romkatalog"</string>
<string name="screen_start_chat_error_starting_chat">"Det oppstod en feil når du prøvde å starte en chat"</string>
</resources>

View file

@ -16,5 +16,6 @@ Je kunt dit op elk gewenst moment wijzigen in de kamerinstellingen."</string>
<string name="screen_create_room_room_name_label">"Naam van de kamer"</string>
<string name="screen_create_room_title">"Creëer een kamer"</string>
<string name="screen_create_room_topic_label">"Onderwerp (optioneel)"</string>
<string name="screen_room_directory_search_title">"Kamergids"</string>
<string name="screen_start_chat_error_starting_chat">"Er is een fout opgetreden bij het starten van een chat"</string>
</resources>

View file

@ -19,5 +19,6 @@ Możesz to zmienić w ustawieniach pokoju."</string>
<string name="screen_create_room_room_visibility_section_title">"Widoczność pomieszczenia"</string>
<string name="screen_create_room_title">"Utwórz pokój"</string>
<string name="screen_create_room_topic_label">"Temat (opcjonalnie)"</string>
<string name="screen_room_directory_search_title">"Katalog pokoi"</string>
<string name="screen_start_chat_error_starting_chat">"Wystąpił błąd podczas próby rozpoczęcia czatu"</string>
</resources>

View file

@ -10,5 +10,6 @@ Você pode mudar isso a qualquer momento nas configurações da sala."</string>
<string name="screen_create_room_room_name_label">"Nome da sala"</string>
<string name="screen_create_room_title">"Criar uma sala"</string>
<string name="screen_create_room_topic_label">"Tópico (opcional)"</string>
<string name="screen_room_directory_search_title">"Diretório de salas"</string>
<string name="screen_start_chat_error_starting_chat">"Ocorreu um erro ao tentar iniciar um chat"</string>
</resources>

View file

@ -19,5 +19,12 @@ Pode alterar esta opção nas definições da sala."</string>
<string name="screen_create_room_room_visibility_section_title">"Visibilidade da sala"</string>
<string name="screen_create_room_title">"Criar uma sala"</string>
<string name="screen_create_room_topic_label">"Descrição (opcional)"</string>
<string name="screen_room_directory_search_title">"Diretório de salas"</string>
<string name="screen_start_chat_error_starting_chat">"Ocorreu um erro ao tentar iniciar uma conversa"</string>
<string name="screen_start_chat_join_room_by_address_action">"Entrar na sala pelo endereço"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Não é um endereço válido"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Entrar…"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Sala correspondente encontrado"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Sala não encontrada"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"por exemplo, #sala:matrix.org"</string>
</resources>

View file

@ -17,5 +17,6 @@ Puteți modifica acest lucru oricând în setări."</string>
<string name="screen_create_room_room_name_label">"Numele camerei"</string>
<string name="screen_create_room_title">"Creați o cameră"</string>
<string name="screen_create_room_topic_label">"Subiect (opțional)"</string>
<string name="screen_room_directory_search_title">"Director de camere"</string>
<string name="screen_start_chat_error_starting_chat">"A apărut o eroare la încercarea începerii conversației"</string>
</resources>

View file

@ -19,5 +19,6 @@
<string name="screen_create_room_room_visibility_section_title">"Видимость комнаты"</string>
<string name="screen_create_room_title">"Создать комнату"</string>
<string name="screen_create_room_topic_label">"Тема (необязательно)"</string>
<string name="screen_room_directory_search_title">"Каталог комнат"</string>
<string name="screen_start_chat_error_starting_chat">"Произошла ошибка при запуске чата"</string>
</resources>

View file

@ -19,6 +19,7 @@ Môžete to kedykoľvek zmeniť v nastaveniach miestnosti."</string>
<string name="screen_create_room_room_visibility_section_title">"Viditeľnosť miestnosti"</string>
<string name="screen_create_room_title">"Vytvoriť miestnosť"</string>
<string name="screen_create_room_topic_label">"Téma (voliteľné)"</string>
<string name="screen_room_directory_search_title">"Adresár miestností"</string>
<string name="screen_start_chat_error_starting_chat">"Pri pokuse o spustenie konverzácie sa vyskytla chyba"</string>
<string name="screen_start_chat_join_room_by_address_action">"Pripojte sa do miestnosti podľa adresy"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Neplatná adresa"</string>

View file

@ -19,5 +19,12 @@ Du kan ändra detta när som helst i rumsinställningarna."</string>
<string name="screen_create_room_room_visibility_section_title">"Rumssynlighet"</string>
<string name="screen_create_room_title">"Skapa ett rum"</string>
<string name="screen_create_room_topic_label">"Ämne (valfritt)"</string>
<string name="screen_room_directory_search_title">"Rumskatalog"</string>
<string name="screen_start_chat_error_starting_chat">"Ett fel uppstod när du försökte starta en chatt"</string>
<string name="screen_start_chat_join_room_by_address_action">"Gå med i rum med adress"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Inte en giltig adress"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Ange …"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Matchande rum hittades"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Rummet hittades inte"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"t.ex. #rumsnamn:matrix.org"</string>
</resources>

View file

@ -19,5 +19,6 @@ Bunu istediğiniz zaman oda ayarlarından değiştirebilirsiniz."</string>
<string name="screen_create_room_room_visibility_section_title">"Oda görünürlüğü"</string>
<string name="screen_create_room_title">"Bir oda oluştur"</string>
<string name="screen_create_room_topic_label">"Konu (isteğe bağlı)"</string>
<string name="screen_room_directory_search_title">"Oda dizini"</string>
<string name="screen_start_chat_error_starting_chat">"Sohbet başlatmaya çalışırken bir hata oluştu"</string>
</resources>

View file

@ -19,5 +19,12 @@
<string name="screen_create_room_room_visibility_section_title">"Видимість кімнати"</string>
<string name="screen_create_room_title">"Створити кімнату"</string>
<string name="screen_create_room_topic_label">"Тема (необов\'язково)"</string>
<string name="screen_room_directory_search_title">"Каталог кімнат"</string>
<string name="screen_start_chat_error_starting_chat">"Під час спроби почати бесіду сталася помилка"</string>
<string name="screen_start_chat_join_room_by_address_action">"Приєднатися до кімнати за адресою"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Недійсна адреса"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Введіть…"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Знайдено відповідну кімнату"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Кімната не знайдена"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"наприклад, #room-name:matrix.org"</string>
</resources>

View file

@ -19,5 +19,6 @@
<string name="screen_create_room_room_visibility_section_title">"聊天室能見度"</string>
<string name="screen_create_room_title">"建立聊天室"</string>
<string name="screen_create_room_topic_label">"主題(非必填)"</string>
<string name="screen_room_directory_search_title">"聊天室目錄"</string>
<string name="screen_start_chat_error_starting_chat">"嘗試開始聊天時發生錯誤"</string>
</resources>

View file

@ -19,5 +19,6 @@
<string name="screen_create_room_room_visibility_section_title">"房间可见性"</string>
<string name="screen_create_room_title">"创建聊天室"</string>
<string name="screen_create_room_topic_label">"主题(可选)"</string>
<string name="screen_room_directory_search_title">"聊天室目录"</string>
<string name="screen_start_chat_error_starting_chat">"在开始聊天时发生了错误"</string>
</resources>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_deactivate_account_confirmation_dialog_content">"Confirma que quieres desactivar tu cuenta. Esta acción no se puede deshacer."</string>
<string name="screen_deactivate_account_delete_all_messages">"Borrar todos mis mensajes"</string>
<string name="screen_deactivate_account_delete_all_messages_notice">"Advertencia: Futuros usuarios pueden ver conversaciones incompletas."</string>
<string name="screen_deactivate_account_description">"Desactivar tu cuenta es %1$s:"</string>
<string name="screen_deactivate_account_description_bold_part">"irreversible"</string>
<string name="screen_deactivate_account_list_item_1">"%1$s tu cuenta (no podrás volver a iniciar sesión y tu ID no se podrá volver a utilizar)."</string>
<string name="screen_deactivate_account_list_item_1_bold_part">"Inhabilitará permanentemente"</string>
<string name="screen_deactivate_account_list_item_2">"Te eliminará de todas las salas de chat."</string>
<string name="screen_deactivate_account_list_item_3">"Eliminará la información de tu cuenta de nuestro servidor de identidad."</string>
<string name="screen_deactivate_account_list_item_4">"Tus mensajes seguirán siendo visibles para los usuarios registrados, pero no estarán disponibles para los usuarios nuevos o no registrados si decides eliminarlos."</string>
<string name="screen_deactivate_account_title">"Desactivar cuenta"</string>
</resources>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_deactivate_account_list_item_2">"Kendu zure burua txat gela guztietatik."</string>
<string name="screen_deactivate_account_title">"Desaktibatu kontua"</string>
</resources>

View file

@ -5,8 +5,10 @@
<string name="screen_deactivate_account_delete_all_messages_notice">"Advarsel: Fremtidige brukere vil kunne se ufullstendige samtaler."</string>
<string name="screen_deactivate_account_description">"Deaktivering av kontoen din er %1$s , det vil:"</string>
<string name="screen_deactivate_account_description_bold_part">"irreversibel"</string>
<string name="screen_deactivate_account_list_item_1">"%1$s kontoen din (du kan ikke logge på igjen, og ID-en din kan ikke brukes på nytt)."</string>
<string name="screen_deactivate_account_list_item_1_bold_part">"Deaktiver permanent"</string>
<string name="screen_deactivate_account_list_item_2">"Fjern deg fra alle chatterom."</string>
<string name="screen_deactivate_account_list_item_3">"Slett kontoinformasjonen din fra vår identitetsserver."</string>
<string name="screen_deactivate_account_list_item_4">"Meldingene dine vil fortsatt være synlige for registrerte brukere, men vil ikke være tilgjengelige for nye eller uregistrerte brukere hvis du velger å slette dem."</string>
<string name="screen_deactivate_account_title">"Deaktiver kontoen"</string>
</resources>

View file

@ -7,7 +7,7 @@
<string name="screen_deactivate_account_description_bold_part">"onomkeerbaar"</string>
<string name="screen_deactivate_account_list_item_1">"Je account %1$s (je kunt niet opnieuw inloggen en je ID kan niet opnieuw worden gebruikt)"</string>
<string name="screen_deactivate_account_list_item_1_bold_part">"permanent uitschakelen"</string>
<string name="screen_deactivate_account_list_item_2">"Je verwijderen uit alle chatrooms."</string>
<string name="screen_deactivate_account_list_item_2">"Je verwijderen uit alle chatkamers."</string>
<string name="screen_deactivate_account_list_item_3">"Je accountgegevens verwijderen van onze identiteitsserver."</string>
<string name="screen_deactivate_account_list_item_4">"Je berichten zijn nog steeds zichtbaar voor geregistreerde gebruikers, maar niet beschikbaar voor nieuwe of niet-geregistreerde gebruikers als je ervoor kiest ze te verwijderen."</string>
<string name="screen_deactivate_account_title">"Account sluiten"</string>

View file

@ -17,4 +17,7 @@ interface EnterpriseService {
fun semanticColorsLight(): SemanticColors
fun semanticColorsDark(): SemanticColors
fun firebasePushGateway(): String?
fun unifiedPushDefaultPushGateway(): String?
}

View file

@ -27,4 +27,7 @@ class DefaultEnterpriseService @Inject constructor() : EnterpriseService {
override fun semanticColorsLight(): SemanticColors = compoundColorsLight
override fun semanticColorsDark(): SemanticColors = compoundColorsDark
override fun firebasePushGateway(): String? = null
override fun unifiedPushDefaultPushGateway(): String? = null
}

View file

@ -19,6 +19,8 @@ class FakeEnterpriseService(
private val defaultHomeserverResult: () -> String? = { A_FAKE_HOMESERVER },
private val semanticColorsLightResult: () -> SemanticColors = { lambdaError() },
private val semanticColorsDarkResult: () -> SemanticColors = { lambdaError() },
private val firebasePushGatewayResult: () -> String? = { lambdaError() },
private val unifiedPushDefaultPushGatewayResult: () -> String? = { lambdaError() },
) : EnterpriseService {
override suspend fun isEnterpriseUser(sessionId: SessionId): Boolean = simulateLongTask {
isEnterpriseUserResult(sessionId)
@ -36,6 +38,14 @@ class FakeEnterpriseService(
return semanticColorsDarkResult()
}
override fun firebasePushGateway(): String? {
return firebasePushGatewayResult()
}
override fun unifiedPushDefaultPushGateway(): String? {
return unifiedPushDefaultPushGatewayResult()
}
companion object {
const val A_FAKE_HOMESERVER = "a_fake_homeserver"
}

View file

@ -1,4 +1,5 @@
import extension.setupAnvil
import org.gradle.kotlin.dsl.test
/*
* Copyright 2023, 2024 New Vector Ltd.
@ -14,6 +15,12 @@ plugins {
android {
namespace = "io.element.android.features.ftue.impl"
testOptions {
unitTests {
isIncludeAndroidResources = true
}
}
}
setupAnvil()
@ -30,6 +37,7 @@ dependencies {
implementation(projects.libraries.uiStrings)
implementation(projects.libraries.testtags)
implementation(projects.features.analytics.api)
implementation(projects.features.logout.api)
implementation(projects.features.securebackup.api)
implementation(projects.features.verifysession.api)
implementation(projects.services.analytics.api)
@ -37,12 +45,16 @@ dependencies {
implementation(projects.libraries.permissions.api)
implementation(projects.libraries.permissions.noop)
implementation(projects.services.toolbox.api)
implementation(projects.appconfig)
testImplementation(libs.test.junit)
testImplementation(libs.coroutines.test)
testImplementation(libs.molecule.runtime)
testImplementation(libs.test.truth)
testImplementation(libs.test.turbine)
testImplementation(libs.test.robolectric)
testImplementation(libs.androidx.compose.ui.test.junit)
testReleaseImplementation(libs.androidx.compose.ui.test.manifest)
testImplementation(projects.libraries.matrix.test)
testImplementation(projects.services.analytics.test)
testImplementation(projects.services.analytics.noop)

View file

@ -16,7 +16,6 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.navigation.backpresshandlerstrategies.BaseBackPressHandlerStrategy
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.navmodel.backstack.BackStack
@ -38,8 +37,6 @@ import io.element.android.libraries.designsystem.theme.components.CircularProgre
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SessionScope
import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
@ -59,7 +56,6 @@ class FtueFlowNode @AssistedInject constructor(
backstack = BackStack(
initialElement = NavTarget.Placeholder,
savedStateMap = buildContext.savedStateMap,
backPressHandler = NoOpBackstackHandlerStrategy(),
),
buildContext = buildContext,
plugins = plugins,
@ -104,7 +100,7 @@ class FtueFlowNode @AssistedInject constructor(
NavTarget.Placeholder -> {
createNode<PlaceholderNode>(buildContext)
}
NavTarget.SessionVerification -> {
is NavTarget.SessionVerification -> {
val callback = object : FtueSessionVerificationFlowNode.Callback {
override fun onDone() {
moveToNextStepIfNeeded()
@ -175,11 +171,3 @@ class FtueFlowNode @AssistedInject constructor(
}
}
}
private class NoOpBackstackHandlerStrategy<NavTarget : Any> : BaseBackPressHandlerStrategy<NavTarget, BackStack.State>() {
override val canHandleBackPressFlow: StateFlow<Boolean> = MutableStateFlow(true)
override fun onBackPressed() {
// No-op
}
}

View file

@ -0,0 +1,23 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.ftue.impl.di
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModePresenter
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeState
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope
@ContributesTo(SessionScope::class)
@Module
interface FtueModule {
@Binds
fun bindChooseSelfVerificationMethodPresenter(presenter: ChooseSelfVerificationModePresenter): Presenter<ChooseSelfVerificationModeState>
}

View file

@ -9,6 +9,7 @@ package io.element.android.features.ftue.impl.sessionverification
import android.os.Parcelable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
import com.bumble.appyx.core.modality.BuildContext
@ -17,15 +18,21 @@ import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.newRoot
import com.bumble.appyx.navmodel.backstack.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.appconfig.LearnMoreConfig
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeNode
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
import io.element.android.features.verifysession.api.VerifySessionEntryPoint
import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.designsystem.utils.OpenUrlInTabView
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.verification.VerificationRequest
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
@ -37,7 +44,7 @@ class FtueSessionVerificationFlowNode @AssistedInject constructor(
private val secureBackupEntryPoint: SecureBackupEntryPoint,
) : BaseFlowNode<FtueSessionVerificationFlowNode.NavTarget>(
backstack = BackStack(
initialElement = NavTarget.Root(showDeviceVerifiedScreen = false),
initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap,
),
buildContext = buildContext,
@ -45,7 +52,10 @@ class FtueSessionVerificationFlowNode @AssistedInject constructor(
) {
sealed interface NavTarget : Parcelable {
@Parcelize
data class Root(val showDeviceVerifiedScreen: Boolean) : NavTarget
data object Root : NavTarget
@Parcelize
data object UseAnotherDevice : NavTarget
@Parcelize
data object EnterRecoveryKey : NavTarget
@ -62,7 +72,7 @@ class FtueSessionVerificationFlowNode @AssistedInject constructor(
override fun onDone() {
lifecycleScope.launch {
// Move to the completed state view in the verification flow
backstack.newRoot(NavTarget.Root(showDeviceVerifiedScreen = true))
backstack.newRoot(NavTarget.UseAnotherDevice)
}
}
}
@ -70,19 +80,43 @@ class FtueSessionVerificationFlowNode @AssistedInject constructor(
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) {
is NavTarget.Root -> {
verifySessionEntryPoint.nodeBuilder(this, buildContext)
.params(VerifySessionEntryPoint.Params(navTarget.showDeviceVerifiedScreen))
.callback(object : VerifySessionEntryPoint.Callback {
override fun onEnterRecoveryKey() {
backstack.push(NavTarget.EnterRecoveryKey)
}
val callback = object : ChooseSelfVerificationModeNode.Callback {
override fun onUseAnotherDevice() {
backstack.push(NavTarget.UseAnotherDevice)
}
override fun onUseRecoveryKey() {
backstack.push(NavTarget.EnterRecoveryKey)
}
override fun onResetKey() {
backstack.push(NavTarget.ResetIdentity)
}
override fun onLearnMoreAboutEncryption() {
learnMoreUrl.value = LearnMoreConfig.ENCRYPTION_URL
}
}
createNode<ChooseSelfVerificationModeNode>(buildContext, plugins = listOf(callback))
}
is NavTarget.UseAnotherDevice -> {
verifySessionEntryPoint.nodeBuilder(this, buildContext)
.params(VerifySessionEntryPoint.Params(
showDeviceVerifiedScreen = true,
verificationRequest = VerificationRequest.Outgoing.CurrentSession,
))
.callback(object : VerifySessionEntryPoint.Callback {
override fun onDone() {
plugins<Callback>().forEach { it.onDone() }
}
override fun onResetKey() {
backstack.push(NavTarget.ResetIdentity)
override fun onBack() {
backstack.pop()
}
override fun onLearnMoreAboutEncryption() {
learnMoreUrl.value = LearnMoreConfig.ENCRYPTION_URL
}
})
.build()
@ -106,8 +140,12 @@ class FtueSessionVerificationFlowNode @AssistedInject constructor(
}
}
private val learnMoreUrl = mutableStateOf<String?>(null)
@Composable
override fun View(modifier: Modifier) {
BackstackView()
OpenUrlInTabView(learnMoreUrl)
}
}

View file

@ -0,0 +1,12 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.ftue.impl.sessionverification.choosemode
sealed interface ChooseSelfVerificationModeEvent {
data object SignOut : ChooseSelfVerificationModeEvent
}

View file

@ -0,0 +1,54 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.ftue.impl.sessionverification.choosemode
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.logout.api.direct.DirectLogoutView
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope
@ContributesNode(SessionScope::class)
class ChooseSelfVerificationModeNode @AssistedInject constructor(
@Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>,
private val presenter: Presenter<ChooseSelfVerificationModeState>,
private val directLogoutView: DirectLogoutView,
) : Node(buildContext, plugins = plugins) {
interface Callback : Plugin {
fun onUseAnotherDevice()
fun onUseRecoveryKey()
fun onResetKey()
fun onLearnMoreAboutEncryption()
}
private val callback = plugins<Callback>().first()
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
ChooseSelfVerificationModeView(
state = state,
onUseAnotherDevice = callback::onUseAnotherDevice,
onUseRecoveryKey = callback::onUseRecoveryKey,
onResetKey = callback::onResetKey,
onLearnMore = callback::onLearnMoreAboutEncryption,
modifier = modifier,
)
directLogoutView.Render(state = state.directLogoutState)
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.ftue.impl.sessionverification.choosemode
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import io.element.android.features.logout.api.direct.DirectLogoutEvents
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.RecoveryState
import javax.inject.Inject
class ChooseSelfVerificationModePresenter @Inject constructor(
private val encryptionService: EncryptionService,
private val directLogoutPresenter: Presenter<DirectLogoutState>,
) : Presenter<ChooseSelfVerificationModeState> {
@Composable
override fun present(): ChooseSelfVerificationModeState {
val isLastDevice by encryptionService.isLastDevice.collectAsState()
val recoveryState by encryptionService.recoveryStateStateFlow.collectAsState()
val canEnterRecoveryKey by remember { derivedStateOf { recoveryState == RecoveryState.INCOMPLETE } }
val directLogoutState = directLogoutPresenter.present()
fun eventHandler(event: ChooseSelfVerificationModeEvent) {
when (event) {
ChooseSelfVerificationModeEvent.SignOut -> directLogoutState.eventSink(DirectLogoutEvents.Logout(ignoreSdkError = false))
}
}
return ChooseSelfVerificationModeState(
isLastDevice = isLastDevice,
canEnterRecoveryKey = canEnterRecoveryKey,
directLogoutState = directLogoutState,
eventSink = ::eventHandler,
)
}
}

View file

@ -0,0 +1,17 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.ftue.impl.sessionverification.choosemode
import io.element.android.features.logout.api.direct.DirectLogoutState
data class ChooseSelfVerificationModeState(
val isLastDevice: Boolean,
val canEnterRecoveryKey: Boolean,
val directLogoutState: DirectLogoutState,
val eventSink: (ChooseSelfVerificationModeEvent) -> Unit,
)

View file

@ -0,0 +1,31 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.ftue.impl.sessionverification.choosemode
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.logout.api.direct.aDirectLogoutState
class ChooseSelfVerificationModeStateProvider :
PreviewParameterProvider<ChooseSelfVerificationModeState> {
override val values = sequenceOf(
aChooseSelfVerificationModeState(isLastDevice = true, canEnterRecoveryKey = true),
aChooseSelfVerificationModeState(isLastDevice = true, canEnterRecoveryKey = false),
aChooseSelfVerificationModeState(isLastDevice = false, canEnterRecoveryKey = true),
aChooseSelfVerificationModeState(isLastDevice = false, canEnterRecoveryKey = false),
)
}
fun aChooseSelfVerificationModeState(
isLastDevice: Boolean = false,
canEnterRecoveryKey: Boolean = true,
) = ChooseSelfVerificationModeState(
isLastDevice = isLastDevice,
canEnterRecoveryKey = canEnterRecoveryKey,
directLogoutState = aDirectLogoutState(),
eventSink = {},
)

View file

@ -0,0 +1,127 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.ftue.impl.sessionverification.choosemode
import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalActivity
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.ftue.impl.R
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.components.BigIcon
import io.element.android.libraries.designsystem.components.PageTitle
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.OutlinedButton
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChooseSelfVerificationModeView(
state: ChooseSelfVerificationModeState,
onUseAnotherDevice: () -> Unit,
onUseRecoveryKey: () -> Unit,
onResetKey: () -> Unit,
onLearnMore: () -> Unit,
modifier: Modifier = Modifier
) {
val activity = LocalActivity.current
BackHandler {
activity?.finish()
}
HeaderFooterPage(
modifier = modifier,
topBar = {
TopAppBar(
title = {},
actions = {
TextButton(
text = stringResource(CommonStrings.action_signout),
onClick = { state.eventSink(ChooseSelfVerificationModeEvent.SignOut) }
)
}
)
},
header = {
PageTitle(
iconStyle = BigIcon.Style.Default(CompoundIcons.LockSolid()),
title = stringResource(id = R.string.screen_identity_confirmation_title),
subtitle = stringResource(id = R.string.screen_identity_confirmation_subtitle)
)
},
footer = {
ButtonColumnMolecule(
modifier = Modifier.padding(bottom = 16.dp)
) {
if (state.isLastDevice.not()) {
Button(
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.screen_identity_use_another_device),
onClick = onUseAnotherDevice,
)
}
if (state.canEnterRecoveryKey) {
Button(
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.screen_session_verification_enter_recovery_key),
onClick = onUseRecoveryKey,
)
}
OutlinedButton(
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.screen_identity_confirmation_cannot_confirm),
onClick = onResetKey,
)
}
}
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
) {
Text(
modifier = Modifier
.clickable(onClick = onLearnMore)
.padding(vertical = 4.dp, horizontal = 16.dp),
text = stringResource(CommonStrings.action_learn_more),
style = ElementTheme.typography.fontBodyLgMedium
)
}
}
}
@PreviewsDayNight
@Composable
internal fun ChooseSelfVerificationModeViewPreview(
@PreviewParameter(ChooseSelfVerificationModeStateProvider::class) state: ChooseSelfVerificationModeState
) = ElementPreview {
ChooseSelfVerificationModeView(
state = state,
onUseAnotherDevice = {},
onUseRecoveryKey = {},
onResetKey = {},
onLearnMore = {},
)
}

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Не можаце пацвердзіць?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Стварыць новы ключ аднаўлення"</string>
<string name="screen_identity_confirmation_subtitle">"Пацвердзіце гэтую прыладу, каб наладзіць бяспечны абмен паведамленнямі."</string>
<string name="screen_identity_confirmation_title">"Пацвердзіце, што гэта вы"</string>
<string name="screen_identity_confirmation_use_another_device">"Выкарыстоўвайце іншую прыладу"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Выкарыстоўваць ключ аднаўлення"</string>
<string name="screen_identity_confirmed_subtitle">"Цяпер вы можаце бяспечна чытаць і адпраўляць паведамленні, і ўсе, з кім вы маеце зносіны ў чаце, таксама могуць давяраць гэтай прыладзе."</string>
<string name="screen_identity_confirmed_title">"Прылада праверана"</string>
<string name="screen_identity_use_another_device">"Выкарыстоўвайце іншую прыладу"</string>
<string name="screen_identity_waiting_on_other_device">"Чаканне на іншай прыладзе…"</string>
<string name="screen_notification_optin_subtitle">"Вы можаце змяніць налады пазней."</string>
<string name="screen_notification_optin_title">"Дазвольце апавяшчэнні і ніколі не прапускайце іх"</string>
<string name="screen_session_verification_enter_recovery_key">"Увядзіце ключ аднаўлення"</string>
<string name="screen_welcome_bullet_1">"Званкі, апытанні, пошук і многае іншае будзе дададзена пазней у гэтым годзе."</string>
<string name="screen_welcome_bullet_2">"Гісторыя паведамленняў для зашыфраваных пакояў пакуль недаступна."</string>
<string name="screen_welcome_bullet_3">"Мы будзем рады пачуць вашае меркаванне, паведаміце нам аб гэтым праз старонку налад."</string>

View file

@ -2,6 +2,7 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_notification_optin_subtitle">"Можете да промените настройките си по-късно."</string>
<string name="screen_notification_optin_title">"Разрешете известията и никога не пропускайте съобщение"</string>
<string name="screen_session_verification_enter_recovery_key">"Въвеждане на ключ за възстановяване"</string>
<string name="screen_welcome_bullet_2">"Хронологията на съобщенията за шифровани стаи все още не е налична."</string>
<string name="screen_welcome_title">"Добре дошли в %1$s!"</string>
</resources>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Nemůžete potvrdit?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Vytvoření nového klíče pro obnovení"</string>
<string name="screen_identity_confirmation_subtitle">"Ověřte toto zařízení a nastavte zabezpečené zasílání zpráv."</string>
<string name="screen_identity_confirmation_title">"Potvrďte, že jste to vy"</string>
<string name="screen_identity_confirmation_use_another_device">"Použít jiné zařízení"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Použít klíč pro obnovení"</string>
<string name="screen_identity_confirmed_subtitle">"Nyní můžete bezpečně číst nebo odesílat zprávy, a kdokoli, s kým chatujete, může tomuto zařízení důvěřovat."</string>
<string name="screen_identity_confirmed_title">"Zařízení ověřeno"</string>
<string name="screen_identity_use_another_device">"Použít jiné zařízení"</string>
<string name="screen_identity_waiting_on_other_device">"Čekání na jiném zařízení…"</string>
<string name="screen_notification_optin_subtitle">"Nastavení můžete později změnit."</string>
<string name="screen_notification_optin_title">"Povolte oznámení a nezmeškejte žádnou zprávu"</string>
<string name="screen_session_verification_enter_recovery_key">"Zadejte klíč pro obnovení"</string>
<string name="screen_welcome_bullet_1">"Hovory, hlasování, vyhledávání a další budou přidány koncem tohoto roku."</string>
<string name="screen_welcome_bullet_2">"Historie zpráv šifrovaných místností nebude v této aktualizaci k dispozici."</string>
<string name="screen_welcome_bullet_3">"Rádi bychom se od vás dozvěděli, co si o tom myslíte, dejte nám vědět prostřednictvím stránky s nastavením."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Sie können es nicht bestätigen?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Erstelle einen neuen Wiederherstellungsschlüssel"</string>
<string name="screen_identity_confirmation_subtitle">"Verifiziere dieses Gerät, um sicheres Messaging einzurichten."</string>
<string name="screen_identity_confirmation_title">"Bestätige, dass du es bist"</string>
<string name="screen_identity_confirmation_use_another_device">"Ein anderes Gerät verwenden"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Wiederherstellungsschlüssel verwenden"</string>
<string name="screen_identity_confirmed_subtitle">"Du kannst nun verschlüsselte Nachrichten lesen oder versenden."</string>
<string name="screen_identity_confirmed_title">"Gerät verifiziert"</string>
<string name="screen_identity_use_another_device">"Ein anderes Gerät verwenden"</string>
<string name="screen_identity_waiting_on_other_device">"Bitte warten bis das andere Gerät bereit ist."</string>
<string name="screen_notification_optin_subtitle">"Du kannst deine Einstellungen später ändern."</string>
<string name="screen_notification_optin_title">"Erlaube Benachrichtigungen und verpasse keine Nachricht"</string>
<string name="screen_session_verification_enter_recovery_key">"Wiederherstellungsschlüssel eingeben"</string>
<string name="screen_welcome_bullet_1">"Anrufe, Umfragen, Suchfunktionen und mehr werden im Laufe des Jahres hinzugefügt."</string>
<string name="screen_welcome_bullet_2">"Der Nachrichtenverlauf für verschlüsselte Räume wird in diesem Update nicht verfügbar sein."</string>
<string name="screen_welcome_bullet_3">"Wir würden uns freuen, von dir zu hören. Teile uns deine Meinung über die Einstellungsseite mit."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Δεν μπορείς να επιβεβαιώσεις;"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Δημιουργία νέου κλειδιού ανάκτησης"</string>
<string name="screen_identity_confirmation_subtitle">"Επαλήθευσε αυτήν τη συσκευή για να ρυθμίσεις την ασφαλή επικοινωνία."</string>
<string name="screen_identity_confirmation_title">"Επιβεβαίωσε ότι είσαι εσύ"</string>
<string name="screen_identity_confirmation_use_another_device">"Χρήση άλλης συσκευής"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Χρήση κλειδιού ανάκτησης"</string>
<string name="screen_identity_confirmed_subtitle">"Τώρα μπορείς να διαβάζεις ή να στέλνεις μηνύματα με ασφάλεια και επίσης μπορεί να εμπιστευτεί αυτήν τη συσκευή οποιοσδήποτε με τον οποίο συνομιλείς."</string>
<string name="screen_identity_confirmed_title">"Επαληθευμένη συσκευή"</string>
<string name="screen_identity_use_another_device">"Χρήση άλλης συσκευής"</string>
<string name="screen_identity_waiting_on_other_device">"Αναμονή σε άλλη συσκευή…"</string>
<string name="screen_notification_optin_subtitle">"Μπορείς να αλλάξεις τις ρυθμίσεις σου αργότερα."</string>
<string name="screen_notification_optin_title">"Επέτρεψε τις ειδοποιήσεις και μην χάσεις ούτε ένα μήνυμα"</string>
<string name="screen_session_verification_enter_recovery_key">"Εισαγωγή κλειδιού ανάκτησης"</string>
<string name="screen_welcome_bullet_1">"Κλήσεις, δημοσκοπήσεις, αναζήτηση και άλλα, θα προστεθούν αργότερα φέτος."</string>
<string name="screen_welcome_bullet_2">"Το ιστορικό μηνυμάτων για κρυπτογραφημένα δωμάτια δεν είναι ακόμα διαθέσιμο."</string>
<string name="screen_welcome_bullet_3">"Θα θέλαμε να ακούσουμε τη γνώμη σου, πες μας τη γνώμη σου μέσω της σελίδας ρυθμίσεων."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"¿No puedes confirmar?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Crear una nueva clave de recuperación"</string>
<string name="screen_identity_confirmation_subtitle">"Verifica este dispositivo para configurar la mensajería segura."</string>
<string name="screen_identity_confirmation_title">"Confirma que eres tú"</string>
<string name="screen_identity_confirmation_use_another_device">"Usar otro dispositivo"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Usar clave de recuperación"</string>
<string name="screen_identity_confirmed_subtitle">"Ahora puedes leer o enviar mensajes de forma segura y cualquier persona con la que chatees también puede confiar en este dispositivo."</string>
<string name="screen_identity_confirmed_title">"Dispositivo verificado"</string>
<string name="screen_identity_use_another_device">"Usar otro dispositivo"</string>
<string name="screen_identity_waiting_on_other_device">"Esperando en otro dispositivo…"</string>
<string name="screen_notification_optin_subtitle">"Puedes cambiar la configuración más tarde."</string>
<string name="screen_notification_optin_title">"Activa las notificaciones y nunca te pierdas un mensaje"</string>
<string name="screen_session_verification_enter_recovery_key">"Introduzca la clave de recuperación"</string>
<string name="screen_welcome_bullet_1">"Las llamadas, las encuestas, la búsqueda y más se agregarán más adelante este año."</string>
<string name="screen_welcome_bullet_2">"El historial de mensajes de las salas cifradas aún no está disponible."</string>
<string name="screen_welcome_bullet_3">"Nos encantaría saber de ti, haznos saber lo que piensas a través de la página de configuración."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Kas kinnitamine pole võimalik?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Loo uus taastevõti"</string>
<string name="screen_identity_confirmation_subtitle">"Krüptitud sõnumivahetuse tagamiseks verifitseeri see seade."</string>
<string name="screen_identity_confirmation_title">"Kinnita, et see oled sina"</string>
<string name="screen_identity_confirmation_use_another_device">"Kasuta teist seadet"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Kasuta taastevõtit"</string>
<string name="screen_identity_confirmed_subtitle">"Nüüd saad saata või lugeda sõnumeid turvaliselt ning kõik sinu vestluspartnerid võivad usaldada seda seadet."</string>
<string name="screen_identity_confirmed_title">"Seade on verifitseeritud"</string>
<string name="screen_identity_use_another_device">"Kasuta teist seadet"</string>
<string name="screen_identity_waiting_on_other_device">"Ootame teise seadme järgi…"</string>
<string name="screen_notification_optin_subtitle">"Sa võid seadistusi hiljem alati muuta."</string>
<string name="screen_notification_optin_title">"Luba teavitused ja kunagi ei jää sul sõnumid märkamata"</string>
<string name="screen_session_verification_enter_recovery_key">"Sisesta taastevõti"</string>
<string name="screen_welcome_bullet_1">"Kõned, küsitlused, otsing ja palju muud lisanduvad hiljem selle aasta jooksul."</string>
<string name="screen_welcome_bullet_2">"Krüptitud jututubade sõnumite ajalugu pole veel saadaval."</string>
<string name="screen_welcome_bullet_3">"Me soovime teada mida sa arvad. Seadistuste lehel olevast valikust võid saata meile oma kommentaare."</string>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Ezin duzu baieztatu?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Sortu berreskuratze-gako berria"</string>
<string name="screen_identity_confirmation_subtitle">"Egiaztatu gailua mezularitza segurua konfiguratzeko."</string>
<string name="screen_identity_confirmation_title">"Berretsi zure identitatea"</string>
<string name="screen_identity_confirmation_use_another_device">"Erabili beste gailu bat"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Erabili berreskuratze-gakoa"</string>
<string name="screen_identity_confirmed_subtitle">"Orain mezuak modu seguruan irakurri edo bidal ditzakezu, eta txateatzen duzun edonor ere fida daiteke gailu honetaz."</string>
<string name="screen_identity_confirmed_title">"Gailua egiaztatu da"</string>
<string name="screen_identity_use_another_device">"Erabili beste gailu bat"</string>
<string name="screen_identity_waiting_on_other_device">"Beste gailuaren zain…"</string>
<string name="screen_notification_optin_subtitle">"Geroago alda ditzakezu ezarpenak."</string>
<string name="screen_notification_optin_title">"Baimendu jakinarazpenak eta ez galdu inoiz mezurik"</string>
<string name="screen_session_verification_enter_recovery_key">"Sartu berreskuratze-gakoa"</string>
<string name="screen_welcome_bullet_1">"Deiak, inkestak, bilaketa eta gehiago gehituko dira aurten."</string>
<string name="screen_welcome_bullet_2">"Enkriptatutako geletarako mezuen historia ez dago oraindik erabilgarri."</string>
<string name="screen_welcome_button">"Goazen!"</string>
<string name="screen_welcome_subtitle">"Hona hemen jakin beharrekoa:"</string>
<string name="screen_welcome_title">"Ongi etorri %1$s(e)ra!"</string>
</resources>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"نمی‌توانید تأیید کنید؟"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"ایجاد کلید بازیابی جدید"</string>
<string name="screen_identity_confirmation_subtitle">"تأیید این افزاره برای برپایی پیام‌رسانی امن."</string>
<string name="screen_identity_confirmation_title">"تأیید هویتتان"</string>
<string name="screen_identity_confirmation_use_another_device">"استفاده از افزاره‌ای دیگر"</string>
<string name="screen_identity_confirmation_use_recovery_key">"استفاده از کلید بازیابی"</string>
<string name="screen_identity_confirmed_subtitle">"اکنون می‌توانید پیام‌ها را به صورت امن فرستاده و بگیرید و هرکسی که با او گپ می‌زنید نیز می‌تواند به این افزاره اعتماد کند."</string>
<string name="screen_identity_confirmed_title">"افزاره تأیید شده"</string>
<string name="screen_identity_use_another_device">"استفاده از افزاره‌ای دیگر"</string>
<string name="screen_identity_waiting_on_other_device">"منتظر افزارهٔ دیگر…"</string>
<string name="screen_notification_optin_subtitle">"می‌توانید بعداً تنظیماتتان را تغییر دهید."</string>
<string name="screen_notification_optin_title">"اجازه به آگاهی‌ها و از دست ندادن پیام‌ها"</string>
<string name="screen_session_verification_enter_recovery_key">"ورود کلید بازیابی"</string>
<string name="screen_welcome_button">"بزن بریم!"</string>
<string name="screen_welcome_subtitle">"چیزهایی که باید بدانید:"</string>
<string name="screen_welcome_title">"به %1$s خوش آمدید!"</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Etkö voi vahvistaa?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Luo uusi palautusavain"</string>
<string name="screen_identity_confirmation_subtitle">"Vahvista tämä laite suojattua viestintää varten."</string>
<string name="screen_identity_confirmation_title">"Vahvista identiteettisi"</string>
<string name="screen_identity_confirmation_use_another_device">"Käytä toista laitetta"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Käytä palautusavainta"</string>
<string name="screen_identity_confirmed_subtitle">"Nyt voit lukea ja lähettää viestejä turvallisesti, ja kaikki, joiden kanssa keskustelet, voivat myös luottaa tähän laitteeseen."</string>
<string name="screen_identity_confirmed_title">"Laite vahvistettu"</string>
<string name="screen_identity_use_another_device">"Käytä toista laitetta"</string>
<string name="screen_identity_waiting_on_other_device">"Odotetaan toista laitetta…"</string>
<string name="screen_notification_optin_subtitle">"Voit muuttaa asetuksia myöhemmin."</string>
<string name="screen_notification_optin_title">"Salli ilmoitukset ja älä koskaan missaa viestejä"</string>
<string name="screen_session_verification_enter_recovery_key">"Syötä palautusavain"</string>
<string name="screen_welcome_bullet_1">"Puhelut, kyselyt, haku ja paljon muuta lisätään myöhemmin tänä vuonna."</string>
<string name="screen_welcome_bullet_2">"Salattujen huoneiden viestihistoria ei ole vielä käytettävissä."</string>
<string name="screen_welcome_bullet_3">"Haluaisimme kuulla mielipiteesi, kerro mitä mieltä olet asetuksien kautta."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Confirmation impossible ?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Créer une nouvelle clé de récupération"</string>
<string name="screen_identity_confirmation_subtitle">"Vérifier cette session pour configurer votre messagerie sécurisée."</string>
<string name="screen_identity_confirmation_title">"Confirmez votre identité"</string>
<string name="screen_identity_confirmation_use_another_device">"Utiliser une autre session"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Utiliser la clé de récupération"</string>
<string name="screen_identity_confirmed_subtitle">"Vous pouvez désormais lire ou envoyer des messages en toute sécurité, et toute personne avec qui vous discutez peut également faire confiance à cette session."</string>
<string name="screen_identity_confirmed_title">"Session vérifiée"</string>
<string name="screen_identity_use_another_device">"Utiliser une autre session"</string>
<string name="screen_identity_waiting_on_other_device">"En attente dune autre session…"</string>
<string name="screen_notification_optin_subtitle">"Vous pourrez modifier vos paramètres ultérieurement."</string>
<string name="screen_notification_optin_title">"Autorisez les notifications et ne manquez aucun message"</string>
<string name="screen_session_verification_enter_recovery_key">"Utiliser la clé de récupération"</string>
<string name="screen_welcome_bullet_1">"Les appels, les sondages, les recherches et plus encore seront ajoutés plus tard cette année."</string>
<string name="screen_welcome_bullet_2">"Lhistorique des messages pour les salons chiffrés ne sera pas disponible dans cette mise à jour."</string>
<string name="screen_welcome_bullet_3">"Nhésitez pas à nous faire part de vos commentaires via lécran des paramètres."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Nem tudja megerősíteni?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Új helyreállítási kulcs létrehozása"</string>
<string name="screen_identity_confirmation_subtitle">"A biztonságos üzenetkezelés beállításához ellenőrizze ezt az eszközt."</string>
<string name="screen_identity_confirmation_title">"Erősítse meg, hogy Ön az"</string>
<string name="screen_identity_confirmation_use_another_device">"Másik eszköz használata"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Helyreállítási kulcs használata"</string>
<string name="screen_identity_confirmed_subtitle">"Mostantól biztonságosan olvashat vagy küldhet üzeneteket, és bármelyik csevegőpartnere megbízhat ebben az eszközben."</string>
<string name="screen_identity_confirmed_title">"Eszköz ellenőrizve"</string>
<string name="screen_identity_use_another_device">"Másik eszköz használata"</string>
<string name="screen_identity_waiting_on_other_device">"Várakozás a másik eszközre…"</string>
<string name="screen_notification_optin_subtitle">"A beállításokat később is módosíthatja."</string>
<string name="screen_notification_optin_title">"Értesítések engedélyezése, hogy soha ne maradjon le egyetlen üzenetről sem"</string>
<string name="screen_session_verification_enter_recovery_key">"Adja meg a helyreállítási kulcsot"</string>
<string name="screen_welcome_bullet_1">"A hívások, szavazások, keresések és egyebek az év további részében kerülnek hozzáadásra."</string>
<string name="screen_welcome_bullet_2">"A titkosított szobák üzenetelőzményei nem lesznek elérhetők ebben a frissítésben."</string>
<string name="screen_welcome_bullet_3">"Szeretnénk hallani a véleményét, ossza meg velünk a beállítások oldalon."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Tidak dapat mengonfirmasi?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Buat kunci pemulihan baru"</string>
<string name="screen_identity_confirmation_subtitle">"Verifikasi perangkat ini untuk menyiapkan perpesanan aman."</string>
<string name="screen_identity_confirmation_title">"Konfirmasi bahwa ini Anda"</string>
<string name="screen_identity_confirmation_use_another_device">"Gunakan perangkat lain"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Gunakan kunci pemulihan"</string>
<string name="screen_identity_confirmed_subtitle">"Sekarang Anda dapat membaca atau mengirim pesan dengan aman, dan siapa pun yang mengobrol dengan Anda juga dapat mempercayai perangkat ini."</string>
<string name="screen_identity_confirmed_title">"Perangkat terverifikasi"</string>
<string name="screen_identity_use_another_device">"Gunakan perangkat lain"</string>
<string name="screen_identity_waiting_on_other_device">"Menunggu di perangkat lain…"</string>
<string name="screen_notification_optin_subtitle">"Anda dapat mengubah pengaturan Anda nanti."</string>
<string name="screen_notification_optin_title">"Izinkan pemberitahuan dan jangan pernah melewatkan pesan"</string>
<string name="screen_session_verification_enter_recovery_key">"Masukkan kunci pemulihan"</string>
<string name="screen_welcome_bullet_1">"Panggilan, pemungutan suara, pencarian, dan lainnya akan ditambahkan di tahun ini."</string>
<string name="screen_welcome_bullet_2">"Riwayat pesan untuk ruangan terenkripsi tidak akan tersedia dalam pembaruan ini."</string>
<string name="screen_welcome_bullet_3">"Kami ingin mendengar dari Anda, beri tahu kami pendapat Anda melalui halaman pengaturan."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Non puoi confermare?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Crea una nuova chiave di recupero"</string>
<string name="screen_identity_confirmation_subtitle">"Verifica questo dispositivo per segnare i tuoi messaggi come sicuri."</string>
<string name="screen_identity_confirmation_title">"Conferma la tua identità"</string>
<string name="screen_identity_confirmation_use_another_device">"Usa un altro dispositivo"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Usa la chiave di recupero"</string>
<string name="screen_identity_confirmed_subtitle">"Ora puoi leggere o inviare messaggi in tutta sicurezza e anche chi chatta con te può fidarsi di questo dispositivo."</string>
<string name="screen_identity_confirmed_title">"Dispositivo verificato"</string>
<string name="screen_identity_use_another_device">"Usa un altro dispositivo"</string>
<string name="screen_identity_waiting_on_other_device">"In attesa sull\'altro dispositivo…"</string>
<string name="screen_notification_optin_subtitle">"Potrai modificare le tue impostazioni in seguito."</string>
<string name="screen_notification_optin_title">"Consenti le notifiche e non perdere mai un messaggio"</string>
<string name="screen_session_verification_enter_recovery_key">"Inserisci la chiave di recupero"</string>
<string name="screen_welcome_bullet_1">"Chiamate, sondaggi, ricerche e altro ancora saranno aggiunti nel corso dell\'anno."</string>
<string name="screen_welcome_bullet_2">"La cronologia dei messaggi per le stanze crittografate non è ancora disponibile."</string>
<string name="screen_welcome_bullet_3">"Ci piacerebbe sentire il tuo parere, facci sapere cosa ne pensi tramite la pagina delle impostazioni."</string>

View file

@ -1,7 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_create_new_recovery_key">"ახალი აღდგენის გასაღების შექმნა"</string>
<string name="screen_identity_confirmation_subtitle">"დაადასტურეთ ეს მოწყობილობა უსაფრთხო მიმოწერისათვის."</string>
<string name="screen_identity_confirmation_title">"დაამტკიცეთ თქვენი პიროვნება"</string>
<string name="screen_identity_confirmed_subtitle">"ახლა თქვენ შეძლებთ შეტყობინებების წაკითხვას ან გაგზავნას უსაფრთხოდ, სხვა მომხმარებლებსაც შეუძლიათ ამ მოწყობილობას ენდონ."</string>
<string name="screen_identity_confirmed_title">"მოწყობილობა დადასტურებულია"</string>
<string name="screen_identity_waiting_on_other_device">"ველოდებით სხვა მოწყობილობას…"</string>
<string name="screen_notification_optin_subtitle">"თქვენ შეგიძლიათ შეცვალოთ თქვენი პარამეტრები მოგვიანებით."</string>
<string name="screen_notification_optin_title">"ყველა შეტყობინებაზე შეტყობინებების მიღება"</string>
<string name="screen_session_verification_enter_recovery_key">"შეიყვანეთ აღდგენის გასაღები"</string>
<string name="screen_welcome_bullet_1">"ზარები, გამოკითხვები, ძიება და სხვა დაემატება ამ წლის ბოლოს."</string>
<string name="screen_welcome_bullet_2">"დაშიფრული ოთახებისთვის შეტყობინებების ისტორია ჯერ არ არის ხელმისაწვდომი."</string>
<string name="screen_welcome_bullet_3">"ჩვენ სიამოვნებით მოვისმინოთ თქვენგან, შეგვატყობინეთ რას ფიქრობთ პარამეტრების გვერდზე."</string>

View file

@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Kan du ikke bekrefte?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Opprett en ny gjenopprettingsnøkkel"</string>
<string name="screen_identity_confirmation_subtitle">"Verifiser denne enheten for å sette opp sikker meldingsutveksling."</string>
<string name="screen_identity_confirmation_title">"Bekreft identiteten din"</string>
<string name="screen_identity_confirmation_use_another_device">"Bruk en annen enhet"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Bruk gjenopprettingsnøkkel"</string>
<string name="screen_identity_confirmed_subtitle">"Nå kan du lese eller sende meldinger på en sikker måte, og alle du chatter med kan også stole på denne enheten."</string>
<string name="screen_identity_confirmed_title">"Enhet verifisert"</string>
<string name="screen_identity_use_another_device">"Bruk en annen enhet"</string>
<string name="screen_identity_waiting_on_other_device">"Venter på en annen enhet…"</string>
<string name="screen_notification_optin_subtitle">"Du kan endre innstillingene dine senere."</string>
<string name="screen_notification_optin_title">"Tillat varslinger og gå aldri glipp av en melding"</string>
<string name="screen_session_verification_enter_recovery_key">"Skriv inn gjenopprettingsnøkkel"</string>
<string name="screen_welcome_bullet_1">"Samtaler, avstemninger, søk og mer vil bli lagt til senere i år."</string>
<string name="screen_welcome_bullet_2">"Meldingshistorikk for krypterte rom er ikke tilgjengelig ennå."</string>
<string name="screen_welcome_bullet_3">"Vi vil gjerne høre fra deg, så la oss få vite hva du synes via innstillingssiden."</string>

Some files were not shown because too many files have changed in this diff Show more