Merge branch 'release/26.01.0'

This commit is contained in:
Jorge Martín 2026-01-14 12:50:37 +01:00
commit 82f8757ec9
2093 changed files with 24097 additions and 8522 deletions

View file

@ -35,6 +35,7 @@ ktlint_standard_class-signature = disabled
ktlint_standard_when-entry-bracing = disabled ktlint_standard_when-entry-bracing = disabled
ktlint_standard_blank-line-between-when-conditions = disabled ktlint_standard_blank-line-between-when-conditions = disabled
ktlint_standard_mixed-condition-operators = disabled ktlint_standard_mixed-condition-operators = disabled
ktlint_standard_no-unused-imports = enabled
[*.java] [*.java]
ij_java_align_consecutive_assignments = false ij_java_align_consecutive_assignments = false

View file

@ -46,6 +46,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }}
ELEMENT_SDK_SENTRY_DSN: ${{ secrets.ELEMENT_SDK_SENTRY_DSN }}
ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }} ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }}
ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }} ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }}
ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }} ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }}
@ -53,7 +54,7 @@ jobs:
run: ./gradlew :app:assembleGplayDebug app:assembleFDroidDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES run: ./gradlew :app:assembleGplayDebug app:assembleFDroidDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES
- name: Upload debug APKs - name: Upload debug APKs
if: ${{ matrix.variant == 'debug' }} if: ${{ matrix.variant == 'debug' }}
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: elementx-debug name: elementx-debug
path: | path: |
@ -61,7 +62,7 @@ jobs:
app/build/outputs/apk/fdroid/debug/*-universal-debug.apk app/build/outputs/apk/fdroid/debug/*-universal-debug.apk
- name: Upload x86_64 APK for Maestro - name: Upload x86_64 APK for Maestro
if: ${{ matrix.variant == 'debug' }} if: ${{ matrix.variant == 'debug' }}
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: elementx-apk-maestro name: elementx-apk-maestro
path: | path: |

View file

@ -54,6 +54,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }}
ELEMENT_SDK_SENTRY_DSN: ${{ secrets.ELEMENT_SDK_SENTRY_DSN }}
ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }} ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }}
ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }} ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }}
ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }} ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }}
@ -61,7 +62,7 @@ jobs:
run: ./gradlew :app:assembleGplayDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES run: ./gradlew :app:assembleGplayDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES
- name: Upload debug Enterprise APKs - name: Upload debug Enterprise APKs
if: ${{ matrix.variant == 'debug' }} if: ${{ matrix.variant == 'debug' }}
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: elementx-enterprise-debug name: elementx-enterprise-debug
path: | path: |

View file

@ -44,7 +44,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
- name: Upload APK as artifact - name: Upload APK as artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: elementx-apk-maestro name: elementx-apk-maestro
path: | path: |
@ -69,7 +69,7 @@ jobs:
# https://github.com/actions/checkout/issues/881 # https://github.com/actions/checkout/issues/881
ref: ${{ github.ref }} ref: ${{ github.ref }}
- name: Download APK artifact from previous job - name: Download APK artifact from previous job
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
name: elementx-apk-maestro name: elementx-apk-maestro
- name: Enable KVM group perms - name: Enable KVM group perms
@ -102,7 +102,7 @@ jobs:
script: | script: |
.github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh app-gplay-x86_64-debug.apk .github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh app-gplay-x86_64-debug.apk
- name: Upload test results - name: Upload test results
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: test-results name: test-results
path: | path: |

View file

@ -30,6 +30,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }}
ELEMENT_SDK_SENTRY_DSN: ${{ secrets.ELEMENT_SDK_SENTRY_DSN }}
ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }} ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }}
ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }} ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }}
ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }} ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }}

View file

@ -42,7 +42,7 @@ jobs:
- name: ✅ Upload kover report - name: ✅ Upload kover report
if: always() if: always()
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: kover-results name: kover-results
path: | path: |
@ -74,7 +74,7 @@ jobs:
run: ./gradlew dependencyCheckAnalyze $CI_GRADLE_ARG_PROPERTIES run: ./gradlew dependencyCheckAnalyze $CI_GRADLE_ARG_PROPERTIES
- name: Upload dependency analysis - name: Upload dependency analysis
if: always() if: always()
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: dependency-analysis name: dependency-analysis
path: build/reports/dependency-check-report.html path: build/reports/dependency-check-report.html

View file

@ -97,7 +97,7 @@ jobs:
run: ./gradlew :tests:konsist:testDebugUnitTest $CI_GRADLE_ARG_PROPERTIES --no-daemon run: ./gradlew :tests:konsist:testDebugUnitTest $CI_GRADLE_ARG_PROPERTIES --no-daemon
- name: Upload reports - name: Upload reports
if: always() if: always()
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: konsist-report name: konsist-report
path: | path: |
@ -174,7 +174,7 @@ jobs:
run: ./gradlew :app:lintGplayDebug :app:lintFdroidDebug lintDebug $CI_GRADLE_ARG_PROPERTIES --continue run: ./gradlew :app:lintGplayDebug :app:lintFdroidDebug lintDebug $CI_GRADLE_ARG_PROPERTIES --continue
- name: Upload reports - name: Upload reports
if: always() if: always()
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: linting-report name: linting-report
path: | path: |
@ -214,7 +214,7 @@ jobs:
run: ./gradlew detekt $CI_GRADLE_ARG_PROPERTIES --no-daemon run: ./gradlew detekt $CI_GRADLE_ARG_PROPERTIES --no-daemon
- name: Upload reports - name: Upload reports
if: always() if: always()
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: detekt-report name: detekt-report
path: | path: |
@ -254,7 +254,7 @@ jobs:
run: ./gradlew ktlintCheck $CI_GRADLE_ARG_PROPERTIES run: ./gradlew ktlintCheck $CI_GRADLE_ARG_PROPERTIES
- name: Upload reports - name: Upload reports
if: always() if: always()
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: ktlint-report name: ktlint-report
path: | path: |
@ -317,7 +317,7 @@ jobs:
# https://github.com/actions/checkout/issues/881 # https://github.com/actions/checkout/issues/881
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }} ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.ref }}
- name: Download reports from previous jobs - name: Download reports from previous jobs
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
- name: Prepare Danger - name: Prepare Danger
if: always() if: always()
run: | run: |

View file

@ -32,13 +32,14 @@ jobs:
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }} ELEMENT_ANDROID_SENTRY_DSN: ${{ secrets.ELEMENT_ANDROID_SENTRY_DSN }}
ELEMENT_SDK_SENTRY_DSN: ${{ secrets.ELEMENT_SDK_SENTRY_DSN }}
ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }} ELEMENT_CALL_SENTRY_DSN: ${{ secrets.ELEMENT_CALL_SENTRY_DSN }}
ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }} ELEMENT_CALL_POSTHOG_API_HOST: ${{ secrets.ELEMENT_CALL_POSTHOG_API_HOST }}
ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }} ELEMENT_CALL_POSTHOG_API_KEY: ${{ secrets.ELEMENT_CALL_POSTHOG_API_KEY }}
ELEMENT_CALL_RAGESHAKE_URL: ${{ secrets.ELEMENT_CALL_RAGESHAKE_URL }} ELEMENT_CALL_RAGESHAKE_URL: ${{ secrets.ELEMENT_CALL_RAGESHAKE_URL }}
run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload bundle as artifact - name: Upload bundle as artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: elementx-app-gplay-bundle-unsigned name: elementx-app-gplay-bundle-unsigned
path: | path: |
@ -74,7 +75,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload bundle as artifact - name: Upload bundle as artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: elementx-enterprise-app-gplay-bundle-unsigned name: elementx-enterprise-app-gplay-bundle-unsigned
path: | path: |
@ -102,7 +103,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
run: ./gradlew assembleFdroidRelease $CI_GRADLE_ARG_PROPERTIES run: ./gradlew assembleFdroidRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload apks as artifact - name: Upload apks as artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: elementx-app-fdroid-apks-unsigned name: elementx-app-fdroid-apks-unsigned
path: | path: |

View file

@ -36,7 +36,7 @@ jobs:
./tools/localazy/importSupportedLocalesFromLocalazy.py ./tools/localazy/importSupportedLocalesFromLocalazy.py
./tools/test/generateAllScreenshots.py ./tools/test/generateAllScreenshots.py
- name: Create Pull Request for Strings - name: Create Pull Request for Strings
uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with: with:
token: ${{ secrets.DANGER_GITHUB_API_TOKEN }} token: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
commit-message: Sync Strings from Localazy commit-message: Sync Strings from Localazy

View file

@ -23,7 +23,7 @@ jobs:
- name: Run SAS String script - name: Run SAS String script
run: ./tools/sas/import_sas_strings.py run: ./tools/sas/import_sas_strings.py
- name: Create Pull Request for SAS Strings - name: Create Pull Request for SAS Strings
uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with: with:
commit-message: Sync SAS Strings commit-message: Sync SAS Strings
title: Sync SAS Strings title: Sync SAS Strings

View file

@ -61,7 +61,7 @@ jobs:
- name: 🚫 Upload kover failed coverage reports - name: 🚫 Upload kover failed coverage reports
if: failure() if: failure()
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: kover-error-report name: kover-error-report
path: | path: |
@ -73,7 +73,7 @@ jobs:
- name: 🚫 Upload test results on error - name: 🚫 Upload test results on error
if: failure() if: failure()
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: tests-and-screenshot-tests-results name: tests-and-screenshot-tests-results
path: | path: |
@ -83,7 +83,7 @@ jobs:
# https://github.com/codecov/codecov-action # https://github.com/codecov/codecov-action
- name: ☂️ Upload coverage reports to codecov - name: ☂️ Upload coverage reports to codecov
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with: with:
fail_ci_if_error: true fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}

4
.idea/kotlinc.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="KotlinJpsPluginSettings"> <component name="KotlinJpsPluginSettings">
<option name="version" value="2.2.20" /> <option name="version" value="2.3.0" />
</component> </component>
</project> </project>

View file

@ -1,3 +1,58 @@
Changes in Element X v25.12.0
=============================
<!-- Release notes generated using configuration in .github/release.yml at v25.12.0 -->
## What's Changed
### ✨ Features
* Room list: enable latest event sorter. by @bmarty in https://github.com/element-hq/element-x-android/pull/5825
* Add room list indicators about last message by @bmarty in https://github.com/element-hq/element-x-android/pull/5824
### 🙌 Improvements
* Change : improve room and space member list by @ganfra in https://github.com/element-hq/element-x-android/pull/5806
* Change : security and privacy rework by @ganfra in https://github.com/element-hq/element-x-android/pull/5816
### 🐛 Bugfixes
* Ensure confirmation dialog is displayed when an admin add other admin to a room by @bmarty in https://github.com/element-hq/element-x-android/pull/5786
* Edit user profile cancel confirmation by @bmarty in https://github.com/element-hq/element-x-android/pull/5788
* Fix editing owner by @bmarty in https://github.com/element-hq/element-x-android/pull/5807
* Uris should take precedence in plain text intents by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5785
* Fix long voice recording by @bmarty in https://github.com/element-hq/element-x-android/pull/5821
### 🗣 Translations
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/5792
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/5830
### 🧱 Build
* Use regex to check forbidden terms by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5784
* Update Gradle Wrapper from 8.14.3 to 9.2.1 by @ElementBot in https://github.com/element-hq/element-x-android/pull/5751
### Dependency upgrades
* fix(deps): update dependency androidx.sqlite:sqlite-ktx to v2.6.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5769
* fix(deps): update datastore to v1.2.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5789
* chore(deps): update peter-evans/create-pull-request action to v7.0.9 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5793
* fix(deps): update dependency io.nlopez.compose.rules:detekt to v0.4.28 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5795
* fix(deps): update metro to v0.7.7 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5771
* chore(deps): update plugin sonarqube to v7.1.0.6387 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5783
* fix(deps): update dependency io.github.sergio-sastre.composablepreviewscanner:android to v0.7.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5799
* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.11.24 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5796
* fix(deps): update dependency io.sentry:sentry-android to v8.27.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5803
* fix(deps): update dependency io.element.android:emojibase-bindings to v1.5.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5801
* fix(deps): update roborazzi to v1.52.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5804
* fix(deps): update dependency org.maplibre.gl:android-sdk to v12.2.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5814
* chore(deps): update actions/checkout action to v6 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5805
* fix(deps): update dependency com.google.testparameterinjector:test-parameter-injector to v1.20 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5800
* fix(deps): update android.gradle.plugin to v8.13.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5260
* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.11.26 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5818
* fix(deps): update dependencyanalysis to v3.5.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5819
* fix(deps): update dependency com.posthog:posthog-android to v3.27.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5834
* fix(deps): update dependency io.element.android:element-call-embedded to v0.16.3 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5839
* Upgrade the Rust SDK to `v25.12.2` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5838
### Others
* misc : use newLatestEvent api from sdk by @ganfra in https://github.com/element-hq/element-x-android/pull/5809
* Inject RoomMemberListDataSource in the presenter constructor. by @bmarty in https://github.com/element-hq/element-x-android/pull/5822
* Add more performance checks by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5767
* Load `JoinedRoom` in home screen, pass it to the room flow by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5817
* Revert "fix(deps): update dependency com.posthog:posthog-android to v3.27.0" by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5836
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v25.11.3...v25.12.0
Changes in Element X v25.11.3 Changes in Element X v25.11.3
============================= =============================

View file

@ -199,6 +199,10 @@ android {
resources.pickFirsts += setOf( resources.pickFirsts += setOf(
"META-INF/versions/9/OSGI-INF/MANIFEST.MF", "META-INF/versions/9/OSGI-INF/MANIFEST.MF",
) )
jniLibs {
useLegacyPackaging = project.findProperty("useLegacyPackaging")?.toString()?.toBoolean()
}
} }
} }

View file

@ -66,7 +66,10 @@
-dontwarn androidx.window.sidecar.SidecarWindowLayoutInfo -dontwarn androidx.window.sidecar.SidecarWindowLayoutInfo
# Also needed after AGP 8.13.1 upgrade, it seems like proguard is now more aggressive on removing unused code # Also needed after AGP 8.13.1 upgrade, it seems like proguard is now more aggressive on removing unused code
-keep class org.matrix.rustcomponents.sdk.** { *;} -keep,allowshrinking class org.matrix.rustcomponents.sdk.** { *;}
-keep class uniffi.** { *;} -keep,allowshrinking class uniffi.** { *;}
-keep class io.element.android.x.di.** { *; } -keep,allowshrinking class io.element.android.x.di.** { *; }
-keepnames class io.element.android.x.** -keepclasseswithmembernames,allowoptimization,allowshrinking class io.element.android.** { *; }
# Keep Metro classes
-keep,allowshrinking class dev.zacsweers.metro.** { *; }

View file

@ -17,6 +17,7 @@ import io.element.android.features.lockscreen.api.LockScreenService
import io.element.android.features.rageshake.api.reporter.BugReporter import io.element.android.features.rageshake.api.reporter.BugReporter
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.identifiers.SentrySdkDsn
import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.matrix.api.platform.InitPlatformService import io.element.android.libraries.matrix.api.platform.InitPlatformService
import io.element.android.libraries.matrix.api.tracing.TracingService import io.element.android.libraries.matrix.api.tracing.TracingService
@ -48,4 +49,6 @@ interface AppBindings {
fun featureFlagService(): FeatureFlagService fun featureFlagService(): FeatureFlagService
fun buildMeta(): BuildMeta fun buildMeta(): BuildMeta
fun sentrySdkDsn(): SentrySdkDsn?
} }

View file

@ -38,6 +38,7 @@ class PlatformInitializer : Initializer<Unit> {
logLevel = logLevel, logLevel = logLevel,
extraTargets = listOf(ELEMENT_X_TARGET), extraTargets = listOf(ELEMENT_X_TARGET),
traceLogPacks = runBlocking { preferencesStore.getTracingLogPacksFlow().first() }, traceLogPacks = runBlocking { preferencesStore.getTracingLogPacksFlow().first() },
sdkSentryDsn = appBindings.sentrySdkDsn()?.value?.takeIf { it.isNotBlank() },
) )
bugReporter.setCurrentTracingLogLevel(logLevel.name) bugReporter.setCurrentTracingLogLevel(logLevel.name)
platformService.init(tracingConfiguration) platformService.init(tracingConfiguration)

View file

@ -15,6 +15,7 @@
<locale android:name="fa"/> <locale android:name="fa"/>
<locale android:name="fi"/> <locale android:name="fi"/>
<locale android:name="fr"/> <locale android:name="fr"/>
<locale android:name="hr"/>
<locale android:name="hu"/> <locale android:name="hu"/>
<locale android:name="in"/> <locale android:name="in"/>
<locale android:name="it"/> <locale android:name="it"/>

View file

@ -13,4 +13,5 @@ object LearnMoreConfig {
const val DEVICE_VERIFICATION_URL: String = "https://element.io/help#encryption-device-verification" const val DEVICE_VERIFICATION_URL: String = "https://element.io/help#encryption-device-verification"
const val SECURE_BACKUP_URL: String = "https://element.io/help#encryption5" const val SECURE_BACKUP_URL: String = "https://element.io/help#encryption5"
const val IDENTITY_CHANGE_URL: String = "https://element.io/help#encryption18" const val IDENTITY_CHANGE_URL: String = "https://element.io/help#encryption18"
const val HISTORY_VISIBLE_URL: String = "https://element.io/en/help#e2ee-history-sharing"
} }

View file

@ -17,19 +17,19 @@ object TimelineConfig {
* Event types that will be filtered out from the timeline (i.e. not displayed). * Event types that will be filtered out from the timeline (i.e. not displayed).
*/ */
val excludedEvents = listOf( val excludedEvents = listOf(
StateEventType.CALL_MEMBER, StateEventType.CallMember,
StateEventType.ROOM_ALIASES, StateEventType.RoomAliases,
StateEventType.ROOM_CANONICAL_ALIAS, StateEventType.RoomCanonicalAlias,
StateEventType.ROOM_GUEST_ACCESS, StateEventType.RoomGuestAccess,
StateEventType.ROOM_HISTORY_VISIBILITY, StateEventType.RoomHistoryVisibility,
StateEventType.ROOM_JOIN_RULES, StateEventType.RoomJoinRules,
StateEventType.ROOM_POWER_LEVELS, StateEventType.RoomPowerLevels,
StateEventType.ROOM_SERVER_ACL, StateEventType.RoomServerAcl,
StateEventType.ROOM_TOMBSTONE, StateEventType.RoomTombstone,
StateEventType.SPACE_CHILD, StateEventType.SpaceChild,
StateEventType.SPACE_PARENT, StateEventType.SpaceParent,
StateEventType.POLICY_RULE_ROOM, StateEventType.PolicyRuleRoom,
StateEventType.POLICY_RULE_SERVER, StateEventType.PolicyRuleServer,
StateEventType.POLICY_RULE_USER, StateEventType.PolicyRuleUser,
) )
} }

View file

@ -48,6 +48,7 @@ dependencies {
implementation(projects.features.announcement.api) implementation(projects.features.announcement.api)
implementation(projects.features.ftue.api) implementation(projects.features.ftue.api)
implementation(projects.features.linknewdevice.api)
implementation(projects.features.share.api) implementation(projects.features.share.api)
implementation(projects.services.apperror.impl) implementation(projects.services.apperror.impl)
@ -62,6 +63,7 @@ dependencies {
testImplementation(projects.libraries.push.test) testImplementation(projects.libraries.push.test)
testImplementation(projects.libraries.pushproviders.test) testImplementation(projects.libraries.pushproviders.test)
testImplementation(projects.features.forward.test) testImplementation(projects.features.forward.test)
testImplementation(projects.features.messages.test)
testImplementation(projects.features.networkmonitor.test) testImplementation(projects.features.networkmonitor.test)
testImplementation(projects.features.rageshake.test) testImplementation(projects.features.rageshake.test)
testImplementation(projects.services.appnavstate.impl) testImplementation(projects.services.appnavstate.impl)

View file

@ -47,12 +47,14 @@ import io.element.android.appnav.room.RoomFlowNode
import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.RoomNavigationTarget
import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
import io.element.android.compound.colors.SemanticColorsLightDark import io.element.android.compound.colors.SemanticColorsLightDark
import io.element.android.features.createroom.api.CreateRoomEntryPoint
import io.element.android.features.enterprise.api.EnterpriseService import io.element.android.features.enterprise.api.EnterpriseService
import io.element.android.features.enterprise.api.SessionEnterpriseService import io.element.android.features.enterprise.api.SessionEnterpriseService
import io.element.android.features.ftue.api.FtueEntryPoint import io.element.android.features.ftue.api.FtueEntryPoint
import io.element.android.features.ftue.api.state.FtueService import io.element.android.features.ftue.api.state.FtueService
import io.element.android.features.ftue.api.state.FtueState import io.element.android.features.ftue.api.state.FtueState
import io.element.android.features.home.api.HomeEntryPoint import io.element.android.features.home.api.HomeEntryPoint
import io.element.android.features.linknewdevice.api.LinkNewDeviceEntryPoint
import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkMonitor
import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.api.NetworkStatus
import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer
@ -123,6 +125,7 @@ class LoggedInFlowNode(
private val secureBackupEntryPoint: SecureBackupEntryPoint, private val secureBackupEntryPoint: SecureBackupEntryPoint,
private val userProfileEntryPoint: UserProfileEntryPoint, private val userProfileEntryPoint: UserProfileEntryPoint,
private val ftueEntryPoint: FtueEntryPoint, private val ftueEntryPoint: FtueEntryPoint,
private val linkNewDeviceEntryPoint: LinkNewDeviceEntryPoint,
@SessionCoroutineScope @SessionCoroutineScope
private val sessionCoroutineScope: CoroutineScope, private val sessionCoroutineScope: CoroutineScope,
private val ftueService: FtueService, private val ftueService: FtueService,
@ -142,6 +145,7 @@ class LoggedInFlowNode(
snackbarDispatcher: SnackbarDispatcher, snackbarDispatcher: SnackbarDispatcher,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher, private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher,
private val createRoomEntryPoint: CreateRoomEntryPoint,
) : BaseFlowNode<LoggedInFlowNode.NavTarget>( ) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
backstack = BackStack( backstack = BackStack(
initialElement = NavTarget.Placeholder, initialElement = NavTarget.Placeholder,
@ -285,6 +289,9 @@ class LoggedInFlowNode(
@Parcelize @Parcelize
data object CreateRoom : NavTarget data object CreateRoom : NavTarget
@Parcelize
data object CreateSpace : NavTarget
@Parcelize @Parcelize
data class SecureBackup( data class SecureBackup(
val initialElement: SecureBackupEntryPoint.InitialTarget = SecureBackupEntryPoint.InitialTarget.Root val initialElement: SecureBackupEntryPoint.InitialTarget = SecureBackupEntryPoint.InitialTarget.Root
@ -293,6 +300,9 @@ class LoggedInFlowNode(
@Parcelize @Parcelize
data object Ftue : NavTarget data object Ftue : NavTarget
@Parcelize
data object LinkNewDevice : NavTarget
@Parcelize @Parcelize
data object RoomDirectory : NavTarget data object RoomDirectory : NavTarget
@ -333,6 +343,10 @@ class LoggedInFlowNode(
backstack.push(NavTarget.CreateRoom) backstack.push(NavTarget.CreateRoom)
} }
override fun navigateToCreateSpace() {
backstack.push(NavTarget.CreateSpace)
}
override fun navigateToSetUpRecovery() { override fun navigateToSetUpRecovery() {
backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.Root)) backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.Root))
} }
@ -419,6 +433,10 @@ class LoggedInFlowNode(
callback.navigateToAddAccount() callback.navigateToAddAccount()
} }
override fun navigateToLinkNewDevice() {
backstack.push(NavTarget.LinkNewDevice)
}
override fun navigateToBugReport() { override fun navigateToBugReport() {
callback.navigateToBugReport() callback.navigateToBugReport()
} }
@ -460,6 +478,14 @@ class LoggedInFlowNode(
callback = callback, callback = callback,
) )
} }
is NavTarget.CreateSpace -> {
val callback = object : CreateRoomEntryPoint.Callback {
override fun onRoomCreated(roomId: RoomId) {
backstack.replace(NavTarget.Room(roomIdOrAlias = RoomIdOrAlias.Id(roomId), serverNames = emptyList()))
}
}
createRoomEntryPoint.createNode(isSpace = true, parentNode = this, buildContext = buildContext, callback = callback)
}
is NavTarget.SecureBackup -> { is NavTarget.SecureBackup -> {
secureBackupEntryPoint.createNode( secureBackupEntryPoint.createNode(
parentNode = this, parentNode = this,
@ -475,6 +501,14 @@ class LoggedInFlowNode(
NavTarget.Ftue -> { NavTarget.Ftue -> {
ftueEntryPoint.createNode(this, buildContext) ftueEntryPoint.createNode(this, buildContext)
} }
NavTarget.LinkNewDevice -> {
val callback = object : LinkNewDeviceEntryPoint.Callback {
override fun onDone() {
backstack.pop()
}
}
linkNewDeviceEntryPoint.createNode(this, buildContext, callback)
}
NavTarget.RoomDirectory -> { NavTarget.RoomDirectory -> {
roomDirectoryEntryPoint.createNode( roomDirectoryEntryPoint.createNode(
parentNode = this, parentNode = this,
@ -499,9 +533,18 @@ class LoggedInFlowNode(
params = ShareEntryPoint.Params(intent = navTarget.intent), params = ShareEntryPoint.Params(intent = navTarget.intent),
callback = object : ShareEntryPoint.Callback { callback = object : ShareEntryPoint.Callback {
override fun onDone(roomIds: List<RoomId>) { override fun onDone(roomIds: List<RoomId>) {
// Remove the incoming share screen
backstack.pop() backstack.pop()
// Navigate to the room if the text/media was shared to a single one
roomIds.singleOrNull()?.let { roomId -> roomIds.singleOrNull()?.let { roomId ->
backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias())) sessionCoroutineScope.launch {
// Wait until the incoming share screen is removed
backstack.elements.first { it.lastOrNull()?.key?.navTarget !is NavTarget.IncomingShare }
// Then attach the room
attachRoom(roomId.toRoomIdOrAlias(), clearBackstack = false)
}
} }
} }
}, },
@ -627,7 +670,21 @@ private class AttachRoomOperation(
operation = this operation = this
) )
} else { } else {
Push<LoggedInFlowNode.NavTarget>(roomTarget).invoke(elements) val existingRoomElement = elements.find {
val roomNavTarget = it.key.navTarget as? LoggedInFlowNode.NavTarget.Room
roomNavTarget?.roomIdOrAlias == roomTarget.roomIdOrAlias
}
if (existingRoomElement != null) {
elements.mapNotNull { element ->
if (element == existingRoomElement) {
null
} else {
element.transitionTo(STASHED, this)
}
} + existingRoomElement.transitionTo(ACTIVE, this)
} else {
Push<LoggedInFlowNode.NavTarget>(roomTarget).invoke(elements)
}
} }
} }
} }

View file

@ -320,7 +320,7 @@ class RootFlowNode(
is ResolvedIntent.Navigation -> { is ResolvedIntent.Navigation -> {
val openingRoomFromNotification = intent.getBooleanExtra(ROOM_OPENED_FROM_NOTIFICATION, false) val openingRoomFromNotification = intent.getBooleanExtra(ROOM_OPENED_FROM_NOTIFICATION, false)
if (openingRoomFromNotification && resolvedIntent.deeplinkData is DeeplinkData.Room) { if (openingRoomFromNotification && resolvedIntent.deeplinkData is DeeplinkData.Room) {
analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline) analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationToMessage)
} }
navigateTo(resolvedIntent.deeplinkData) navigateTo(resolvedIntent.deeplinkData)
} }

View file

@ -14,10 +14,13 @@ import com.bumble.appyx.core.state.SavedStateMap
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.SingleIn import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.androidutils.hash.hash
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analyticsproviders.api.AnalyticsUserData
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
@ -36,6 +39,7 @@ private const val SAVE_INSTANCE_KEY = "io.element.android.x.di.MatrixClientsHold
class MatrixSessionCache( class MatrixSessionCache(
private val authenticationService: MatrixAuthenticationService, private val authenticationService: MatrixAuthenticationService,
private val syncOrchestratorFactory: SyncOrchestrator.Factory, private val syncOrchestratorFactory: SyncOrchestrator.Factory,
private val analyticsService: AnalyticsService,
) : MatrixClientProvider { ) : MatrixClientProvider {
private val sessionIdsToMatrixSession = ConcurrentHashMap<SessionId, InMemoryMatrixSession>() private val sessionIdsToMatrixSession = ConcurrentHashMap<SessionId, InMemoryMatrixSession>()
private val restoreMutex = Mutex() private val restoreMutex = Mutex()
@ -100,6 +104,11 @@ class MatrixSessionCache(
Timber.d("Restore matrix session: $sessionId") Timber.d("Restore matrix session: $sessionId")
return authenticationService.restoreSession(sessionId) return authenticationService.restoreSession(sessionId)
.onSuccess { matrixClient -> .onSuccess { matrixClient ->
// Add the current homeserver (hashed) to the extra info
// This may not play well with multiple sessions, but it should work for now
analyticsService.addIndexableData(AnalyticsUserData.HOMESERVER, matrixClient.userIdServerName().hash())
// Add the new client to the in-memory cache
onNewMatrixClient(matrixClient) onNewMatrixClient(matrixClient)
} }
.onFailure { .onFailure {

View file

@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.api.recordTransaction import io.element.android.services.analytics.api.recordTransaction
import io.element.android.services.analyticsproviders.api.AnalyticsUserData
import io.element.android.services.appnavstate.api.AppForegroundStateService import io.element.android.services.appnavstate.api.AppForegroundStateService
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.FlowPreview
@ -77,7 +78,7 @@ class SyncOrchestrator(
// Wait until the sync service is not idle, either it will be running or in error/offline state // Wait until the sync service is not idle, either it will be running or in error/offline state
val firstState = syncService.syncState.first { it != SyncState.Idle } val firstState = syncService.syncState.first { it != SyncState.Idle }
transaction.setData("first_sync_state", firstState.name) transaction.putIndexableData(AnalyticsUserData.FIRST_SYNC_STATE, firstState.name)
} }
observeStates() observeStates()

View file

@ -10,8 +10,10 @@ package io.element.android.appnav.di
import io.element.android.features.messages.api.pinned.PinnedEventsTimelineProvider import io.element.android.features.messages.api.pinned.PinnedEventsTimelineProvider
import io.element.android.libraries.matrix.api.timeline.TimelineProvider import io.element.android.libraries.matrix.api.timeline.TimelineProvider
import io.element.android.services.analytics.api.watchers.AnalyticsSendMessageWatcher
interface TimelineBindings { interface TimelineBindings {
val timelineProvider: TimelineProvider val timelineProvider: TimelineProvider
val pinnedEventsTimelineProvider: PinnedEventsTimelineProvider val pinnedEventsTimelineProvider: PinnedEventsTimelineProvider
val analyticsSendMessageWatcher: AnalyticsSendMessageWatcher
} }

View file

@ -49,7 +49,7 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
import io.element.android.libraries.matrix.ui.room.LoadingRoomState import io.element.android.libraries.matrix.ui.room.LoadingRoomState
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadJoinedRoomFlow import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadJoinedRoomFlow
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationToMessage
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
@ -128,7 +128,7 @@ class RoomFlowNode(
override fun onBuilt() { override fun onBuilt() {
super.onBuilt() super.onBuilt()
val parentTransaction = analyticsService.getLongRunningTransaction(NotificationTapOpensTimeline) val parentTransaction = analyticsService.getLongRunningTransaction(NotificationToMessage)
val openRoomTransaction = analyticsService.startLongRunningTransaction(OpenRoom, parentTransaction) val openRoomTransaction = analyticsService.startLongRunningTransaction(OpenRoom, parentTransaction)
analyticsService.startLongRunningTransaction(LoadJoinedRoomFlow, openRoomTransaction) analyticsService.startLongRunningTransaction(LoadJoinedRoomFlow, openRoomTransaction)
resolveRoomId() resolveRoomId()

View file

@ -8,7 +8,9 @@
package io.element.android.appnav.room.joined package io.element.android.appnav.room.joined
import android.app.Activity
import android.os.Parcelable import android.os.Parcelable
import androidx.activity.compose.LocalActivity
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -96,6 +98,11 @@ class JoinedRoomLoadedFlowNode(
private val callback: Callback = callback() private val callback: Callback = callback()
override val graph = roomGraphFactory.create(inputs.room) override val graph = roomGraphFactory.create(inputs.room)
private val sendMessageWatcher = (graph as? TimelineBindings)?.analyticsSendMessageWatcher
// This is an ugly hack to check activity recreation
private var currentActivity: Activity? = null
init { init {
lifecycle.subscribe( lifecycle.subscribe(
onCreate = { onCreate = {
@ -104,6 +111,7 @@ class JoinedRoomLoadedFlowNode(
Timber.v("OnCreate => ${inputs.room.roomId}") Timber.v("OnCreate => ${inputs.room.roomId}")
appNavigationStateService.onNavigateToRoom(id, inputs.room.roomId) appNavigationStateService.onNavigateToRoom(id, inputs.room.roomId)
activeRoomsHolder.addRoom(inputs.room) activeRoomsHolder.addRoom(inputs.room)
sendMessageWatcher?.start()
fetchRoomMembers() fetchRoomMembers()
trackVisitedRoom() trackVisitedRoom()
}, },
@ -115,8 +123,13 @@ class JoinedRoomLoadedFlowNode(
}, },
onDestroy = { onDestroy = {
Timber.v("OnDestroy") Timber.v("OnDestroy")
activeRoomsHolder.removeRoom(inputs.room.sessionId, inputs.room.roomId) sendMessageWatcher?.stop()
inputs.room.destroy() // If we're just going through an activity recreation there's no need to destroy the Room object
// Destroying it would actually cause an issue where its methods can no longer be called
if (currentActivity?.isChangingConfigurations != true) {
activeRoomsHolder.removeRoom(inputs.room.sessionId, inputs.room.roomId)
inputs.room.destroy()
}
appNavigationStateService.onLeavingRoom(id) appNavigationStateService.onLeavingRoom(id)
} }
) )
@ -289,6 +302,8 @@ class JoinedRoomLoadedFlowNode(
@Composable @Composable
override fun View(modifier: Modifier) { override fun View(modifier: Modifier) {
currentActivity = LocalActivity.current
BackstackView() BackstackView()
} }
} }

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">"Odjava i nadogradnja"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s više ne podržava stari protokol. Odjavite se i ponovno prijavite kako biste se nastavili služiti aplikacijom."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Vaš matični poslužitelj više ne podržava stari protokol. Odjavite se i ponovno prijavite kako biste se nastavili služiti aplikacijom."</string>
</resources>

View file

@ -19,22 +19,29 @@ import com.bumble.appyx.testing.junit4.util.MainDispatcherRule
import com.bumble.appyx.testing.unit.common.helper.parentNodeTestHelper import com.bumble.appyx.testing.unit.common.helper.parentNodeTestHelper
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.appnav.di.RoomGraphFactory import io.element.android.appnav.di.RoomGraphFactory
import io.element.android.appnav.di.TimelineBindings
import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.RoomNavigationTarget
import io.element.android.appnav.room.joined.FakeJoinedRoomLoadedFlowNodeCallback import io.element.android.appnav.room.joined.FakeJoinedRoomLoadedFlowNodeCallback
import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.features.forward.api.ForwardEntryPoint
import io.element.android.features.forward.test.FakeForwardEntryPoint import io.element.android.features.forward.test.FakeForwardEntryPoint
import io.element.android.features.messages.api.MessagesEntryPoint import io.element.android.features.messages.api.MessagesEntryPoint
import io.element.android.features.messages.api.pinned.PinnedEventsTimelineProvider
import io.element.android.features.messages.test.pinned.FakePinnedEventsTimelineProvider
import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint
import io.element.android.features.space.api.SpaceEntryPoint import io.element.android.features.space.api.SpaceEntryPoint
import io.element.android.libraries.architecture.childNode import io.element.android.libraries.architecture.childNode
import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeBaseRoom
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.timeline.FakeTimelineProvider
import io.element.android.services.analytics.api.watchers.AnalyticsSendMessageWatcher
import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.services.analytics.test.watchers.FakeAnalyticsSendMessageWatcher
import io.element.android.services.appnavstate.api.ActiveRoomsHolder import io.element.android.services.appnavstate.api.ActiveRoomsHolder
import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder
import io.element.android.services.appnavstate.test.FakeAppNavigationStateService import io.element.android.services.appnavstate.test.FakeAppNavigationStateService
@ -72,9 +79,20 @@ class JoinedRoomLoadedFlowNodeTest {
} }
} }
private class FakeRoomGraphFactory : RoomGraphFactory { private class FakeRoomGraphFactory(
private val timelineProvider: FakeTimelineProvider = FakeTimelineProvider(),
private val pinnedEventsTimelineProvider: FakePinnedEventsTimelineProvider = FakePinnedEventsTimelineProvider(),
private val analyticsSendMessageWatcher: FakeAnalyticsSendMessageWatcher = FakeAnalyticsSendMessageWatcher(),
) : RoomGraphFactory {
override fun create(room: JoinedRoom): Any { override fun create(room: JoinedRoom): Any {
return Unit return object : TimelineBindings {
override val timelineProvider: TimelineProvider
get() = this@FakeRoomGraphFactory.timelineProvider
override val pinnedEventsTimelineProvider: PinnedEventsTimelineProvider
get() = this@FakeRoomGraphFactory.pinnedEventsTimelineProvider
override val analyticsSendMessageWatcher: AnalyticsSendMessageWatcher
get() = this@FakeRoomGraphFactory.analyticsSendMessageWatcher
}
} }
} }

View file

@ -19,29 +19,31 @@ import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.services.appnavstate.test.FakeAppForegroundStateService import io.element.android.services.appnavstate.test.FakeAppForegroundStateService
import io.element.android.tests.testutils.testCoroutineDispatchers import io.element.android.tests.testutils.testCoroutineDispatchers
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Test import org.junit.Test
@OptIn(ExperimentalCoroutinesApi::class)
class MatrixSessionCacheTest { class MatrixSessionCacheTest {
@Test @Test
fun `test getOrNull`() = runTest { fun `test getOrNull`() = runTest {
val fakeAuthenticationService = FakeMatrixAuthenticationService() val matrixSessionCache = createMatrixSessionCache()
val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory())
assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull()
} }
@Test @Test
fun `test getSyncOrchestratorOrNull`() = runTest { fun `test getSyncOrchestratorOrNull`() = runTest {
val fakeAuthenticationService = FakeMatrixAuthenticationService() val fakeAuthenticationService = FakeMatrixAuthenticationService()
val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService)
// With no matrix client there is no sync orchestrator // With no matrix client there is no sync orchestrator
assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull()
assertThat(matrixSessionCache.getSyncOrchestrator(A_SESSION_ID)).isNull() assertThat(matrixSessionCache.getSyncOrchestrator(A_SESSION_ID)).isNull()
// But as soon as we receive a client, we can get the sync orchestrator // But as soon as we receive a client, we can get the sync orchestrator
val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value })
fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient)
assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient)
assertThat(matrixSessionCache.getSyncOrchestrator(A_SESSION_ID)).isNotNull() assertThat(matrixSessionCache.getSyncOrchestrator(A_SESSION_ID)).isNotNull()
@ -50,8 +52,8 @@ class MatrixSessionCacheTest {
@Test @Test
fun `test getOrRestore`() = runTest { fun `test getOrRestore`() = runTest {
val fakeAuthenticationService = FakeMatrixAuthenticationService() val fakeAuthenticationService = FakeMatrixAuthenticationService()
val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService)
val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value })
fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient)
assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull()
assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient)
@ -63,8 +65,8 @@ class MatrixSessionCacheTest {
@Test @Test
fun `test remove`() = runTest { fun `test remove`() = runTest {
val fakeAuthenticationService = FakeMatrixAuthenticationService() val fakeAuthenticationService = FakeMatrixAuthenticationService()
val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService)
val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value })
fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient)
assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient)
assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient)
@ -76,8 +78,8 @@ class MatrixSessionCacheTest {
@Test @Test
fun `test remove all`() = runTest { fun `test remove all`() = runTest {
val fakeAuthenticationService = FakeMatrixAuthenticationService() val fakeAuthenticationService = FakeMatrixAuthenticationService()
val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService)
val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value })
fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient)
assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient)
assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient) assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient)
@ -89,8 +91,8 @@ class MatrixSessionCacheTest {
@Test @Test
fun `test save and restore`() = runTest { fun `test save and restore`() = runTest {
val fakeAuthenticationService = FakeMatrixAuthenticationService() val fakeAuthenticationService = FakeMatrixAuthenticationService()
val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService)
val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope) val fakeMatrixClient = FakeMatrixClient(sessionCoroutineScope = backgroundScope, userIdServerNameLambda = { A_SESSION_ID.value })
fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient)
matrixSessionCache.getOrRestore(A_SESSION_ID) matrixSessionCache.getOrRestore(A_SESSION_ID)
val savedStateMap = MutableSavedStateMapImpl { true } val savedStateMap = MutableSavedStateMapImpl { true }
@ -109,29 +111,45 @@ class MatrixSessionCacheTest {
@Test @Test
fun `test AuthenticationService listenToNewMatrixClients emits a Client value and we save it`() = runTest { fun `test AuthenticationService listenToNewMatrixClients emits a Client value and we save it`() = runTest {
val fakeAuthenticationService = FakeMatrixAuthenticationService() val fakeAuthenticationService = FakeMatrixAuthenticationService()
val matrixSessionCache = MatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory()) val matrixSessionCache = createMatrixSessionCache(fakeAuthenticationService, createSyncOrchestratorFactory())
assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull() assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNull()
fakeAuthenticationService.givenMatrixClient(FakeMatrixClient(sessionId = A_SESSION_ID, sessionCoroutineScope = backgroundScope))
val loginSucceeded = fakeAuthenticationService.login("user", "pass") val loginSucceeded = fakeAuthenticationService.login("user", "pass")
assertThat(loginSucceeded.isSuccess).isTrue() assertThat(loginSucceeded.isSuccess).isTrue()
runCurrent()
assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNotNull() assertThat(matrixSessionCache.getOrNull(A_SESSION_ID)).isNotNull()
} }
private fun TestScope.createSyncOrchestratorFactory() = object : SyncOrchestrator.Factory { private fun TestScope.createMatrixSessionCache(
override fun create( authenticationService: FakeMatrixAuthenticationService = FakeMatrixAuthenticationService(),
syncService: SyncService, syncOrchestratorFactory: SyncOrchestrator.Factory = createSyncOrchestratorFactory(),
sessionCoroutineScope: CoroutineScope, analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
): SyncOrchestrator { ) = MatrixSessionCache(
return SyncOrchestrator( authenticationService = authenticationService,
syncService = syncService, syncOrchestratorFactory = syncOrchestratorFactory,
sessionCoroutineScope = sessionCoroutineScope, analyticsService = analyticsService,
appForegroundStateService = FakeAppForegroundStateService(), )
networkMonitor = FakeNetworkMonitor(),
dispatchers = testCoroutineDispatchers(), private fun TestScope.createSyncOrchestratorFactory(): SyncOrchestrator.Factory {
analyticsService = FakeAnalyticsService(), val dispatchers = testCoroutineDispatchers()
)
return object : SyncOrchestrator.Factory {
override fun create(
syncService: SyncService,
sessionCoroutineScope: CoroutineScope,
): SyncOrchestrator {
return SyncOrchestrator(
syncService = syncService,
sessionCoroutineScope = sessionCoroutineScope,
appForegroundStateService = FakeAppForegroundStateService(),
networkMonitor = FakeNetworkMonitor(),
dispatchers = dispatchers,
analyticsService = FakeAnalyticsService(),
)
}
} }
} }
} }

View file

@ -46,7 +46,7 @@ allprojects {
config.from(files("$rootDir/tools/detekt/detekt.yml")) config.from(files("$rootDir/tools/detekt/detekt.yml"))
} }
dependencies { dependencies {
detektPlugins("io.nlopez.compose.rules:detekt:0.4.28") detektPlugins("io.nlopez.compose.rules:detekt:0.5.3")
detektPlugins(project(":tests:detekt-rules")) detektPlugins(project(":tests:detekt-rules"))
} }

View file

@ -91,7 +91,7 @@ class ContributesNodeProcessor(
.addAnnotation(Binds::class) .addAnnotation(Binds::class)
.addAnnotation(IntoMap::class) .addAnnotation(IntoMap::class)
.addAnnotation( .addAnnotation(
AnnotationSpec.Companion.builder(ClassName.bestGuess(nodeKeyFqName.asString())).addMember( AnnotationSpec.builder(ClassName.bestGuess(nodeKeyFqName.asString())).addMember(
CLASS_PLACEHOLDER, CLASS_PLACEHOLDER,
ClassName.bestGuess(ksClass.qualifiedName!!.asString()) ClassName.bestGuess(ksClass.qualifiedName!!.asString())
).build() ).build()

View file

@ -0,0 +1,2 @@
Main changes in this version: iterated on spaces, improved the room list stability and performance, and a long list of bug fixes.
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">"Podijelite anonimne podatke o korištenju kako biste nam pomogli u otkrivanju problema."</string>
<string name="screen_analytics_settings_read_terms">"Možete pročitati sve naše uvjete %1$s ."</string>
<string name="screen_analytics_settings_read_terms_content_link">"ovdje"</string>
<string name="screen_analytics_settings_share_data">"Dijeljenje analitičkih podataka"</string>
</resources>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_prompt_data_usage">"Nećemo bilježiti niti profilirati nikakve osobne podatke"</string>
<string name="screen_analytics_prompt_help_us_improve">"Podijelite anonimne podatke o korištenju kako biste nam pomogli u otkrivanju problema."</string>
<string name="screen_analytics_prompt_read_terms">"Možete pročitati sve naše uvjete %1$s ."</string>
<string name="screen_analytics_prompt_read_terms_content_link">"ovdje"</string>
<string name="screen_analytics_prompt_settings">"Ovo možete isključiti u bilo kojem trenutku"</string>
<string name="screen_analytics_prompt_third_party_sharing">"Nećemo dijeliti vaše podatke s trećim stranama"</string>
<string name="screen_analytics_prompt_title">"Pomozite nam poboljšati %1$s"</string>
</resources>

View file

@ -81,7 +81,7 @@ private fun SpaceAnnouncementHeader(
showBetaLabel = true, showBetaLabel = true,
subTitle = stringResource(id = R.string.screen_space_announcement_subtitle), subTitle = stringResource(id = R.string.screen_space_announcement_subtitle),
iconStyle = BigIcon.Style.Default( iconStyle = BigIcon.Style.Default(
vectorIcon = CompoundIcons.WorkspaceSolid(), vectorIcon = CompoundIcons.SpaceSolid(),
usePrimaryTint = true, usePrimaryTint = true,
), ),
) )

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Pregledajte prostore koje ste stvorili ili kojima ste se pridružili"</string>
<string name="screen_space_announcement_item2">"Prihvatite ili odbijte pozivnice za prostore"</string>
<string name="screen_space_announcement_item3">"Otkrijte sve sobe kojima se možete pridružiti u svojim prostorima"</string>
<string name="screen_space_announcement_item4">"Pridružite se javnim prostorima"</string>
<string name="screen_space_announcement_item5">"Napustite sve prostore kojima ste se pridružili"</string>
<string name="screen_space_announcement_notice">"Uskoro stiže filtriranje i stvaranje prostora te upravljanje njima."</string>
<string name="screen_space_announcement_subtitle">"Dobrodošli u beta inačicu prostora! S ovom prvom inačicom možete:"</string>
<string name="screen_space_announcement_title">"Predstavljamo prostore"</string>
</resources>

View file

@ -5,7 +5,7 @@
<string name="screen_space_announcement_item3">"Descoperiți toate camerele la care vă puteți alătura în spațiile dumneavoastră."</string> <string name="screen_space_announcement_item3">"Descoperiți toate camerele la care vă puteți alătura în spațiile dumneavoastră."</string>
<string name="screen_space_announcement_item4">"Alăturați-vă spațiilor publice"</string> <string name="screen_space_announcement_item4">"Alăturați-vă spațiilor publice"</string>
<string name="screen_space_announcement_item5">"Părăsiți spațiile la care v-ați alăturat."</string> <string name="screen_space_announcement_item5">"Părăsiți spațiile la care v-ați alăturat."</string>
<string name="screen_space_announcement_notice">"Crearea și gestionarea spațiilor vor fi disponibile în curând."</string> <string name="screen_space_announcement_notice">"Filtrarea, crearea și gestionarea spațiilor vor fi disponibile în curând."</string>
<string name="screen_space_announcement_subtitle">"Bun venit la versiunea beta a Spațiilor! Cu această primă versiune puteți:"</string> <string name="screen_space_announcement_subtitle">"Bun venit la versiunea beta a Spațiilor! Cu această primă versiune puteți:"</string>
<string name="screen_space_announcement_title">"Vă prezentăm Spații"</string> <string name="screen_space_announcement_title">"Vă prezentăm Spații"</string>
</resources> </resources>

View file

@ -177,8 +177,8 @@ class DefaultActiveCallManager(
suspend fun incomingCallTimedOut(displayMissedCallNotification: Boolean) = mutex.withLock { suspend fun incomingCallTimedOut(displayMissedCallNotification: Boolean) = mutex.withLock {
Timber.tag(tag).d("Incoming call timed out") Timber.tag(tag).d("Incoming call timed out")
val previousActiveCall = activeCall.value ?: return val previousActiveCall = activeCall.value ?: return@withLock
val notificationData = (previousActiveCall.callState as? CallState.Ringing)?.notificationData ?: return val notificationData = (previousActiveCall.callState as? CallState.Ringing)?.notificationData ?: return@withLock
activeCall.value = null activeCall.value = null
if (activeWakeLock?.isHeld == true) { if (activeWakeLock?.isHeld == true) {
Timber.tag(tag).d("Releasing partial wakelock after timeout") Timber.tag(tag).d("Releasing partial wakelock after timeout")
@ -196,11 +196,11 @@ class DefaultActiveCallManager(
Timber.tag(tag).d("Hung up call: $callType") Timber.tag(tag).d("Hung up call: $callType")
val currentActiveCall = activeCall.value ?: run { val currentActiveCall = activeCall.value ?: run {
Timber.tag(tag).w("No active call, ignoring hang up") Timber.tag(tag).w("No active call, ignoring hang up")
return return@withLock
} }
if (currentActiveCall.callType != callType) { if (currentActiveCall.callType != callType) {
Timber.tag(tag).w("Call type $callType does not match the active call type, ignoring") Timber.tag(tag).w("Call type $callType does not match the active call type, ignoring")
return return@withLock
} }
if (currentActiveCall.callState is CallState.Ringing) { if (currentActiveCall.callState is CallState.Ringing) {
// Decline the call // Decline the call

View file

@ -0,0 +1,8 @@
<?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">"Poziv u tijeku"</string>
<string name="call_foreground_service_message_android">"Dodirnite za povratak u poziv"</string>
<string name="call_foreground_service_title_android">"☎️ Poziv u tijeku"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"Element Call ne podržava korištenje Bluetooth audiouređaja u ovoj inačici Androida. Odaberite drugi audiouređaj."</string>
<string name="screen_incoming_call_subtitle_android">"Dolazni Element Call"</string>
</resources>

View file

@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
interface CreateRoomEntryPoint : FeatureEntryPoint { interface CreateRoomEntryPoint : FeatureEntryPoint {
fun createNode( fun createNode(
isSpace: Boolean,
parentNode: Node, parentNode: Node,
buildContext: BuildContext, buildContext: BuildContext,
callback: Callback, callback: Callback,

View file

@ -24,6 +24,7 @@ import io.element.android.features.createroom.impl.addpeople.AddPeopleNode
import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode
import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BackstackView
import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.callback
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ -37,23 +38,29 @@ class CreateRoomFlowNode(
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
) : BaseFlowNode<CreateRoomFlowNode.NavTarget>( ) : BaseFlowNode<CreateRoomFlowNode.NavTarget>(
backstack = BackStack( backstack = BackStack(
initialElement = NavTarget.ConfigureRoom, initialElement = NavTarget.ConfigureRoom(isSpace = plugins.filterIsInstance<Inputs>().first().isSpace),
savedStateMap = buildContext.savedStateMap, savedStateMap = buildContext.savedStateMap,
), ),
buildContext = buildContext, buildContext = buildContext,
plugins = plugins plugins = plugins
) { ) {
@Parcelize
data class Inputs(
val isSpace: Boolean
) : NodeInputs, Parcelable
private val callback: CreateRoomEntryPoint.Callback = callback() private val callback: CreateRoomEntryPoint.Callback = callback()
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) { return when (navTarget) {
NavTarget.ConfigureRoom -> { is NavTarget.ConfigureRoom -> {
val inputs = ConfigureRoomNode.Inputs(isSpace = navTarget.isSpace)
val callback = object : ConfigureRoomNode.Callback { val callback = object : ConfigureRoomNode.Callback {
override fun onCreateRoomSuccess(roomId: RoomId) { override fun onCreateRoomSuccess(roomId: RoomId) {
backstack.replace(NavTarget.AddPeople(roomId)) backstack.replace(NavTarget.AddPeople(roomId))
} }
} }
createNode<ConfigureRoomNode>(buildContext, plugins = listOf(callback)) createNode<ConfigureRoomNode>(buildContext, plugins = listOf(inputs, callback))
} }
is NavTarget.AddPeople -> { is NavTarget.AddPeople -> {
val inputs = AddPeopleNode.Inputs(navTarget.roomId) val inputs = AddPeopleNode.Inputs(navTarget.roomId)
@ -74,7 +81,7 @@ class CreateRoomFlowNode(
sealed interface NavTarget : Parcelable { sealed interface NavTarget : Parcelable {
@Parcelize @Parcelize
data object ConfigureRoom : NavTarget data class ConfigureRoom(val isSpace: Boolean) : NavTarget
@Parcelize @Parcelize
data class AddPeople(val roomId: RoomId) : NavTarget data class AddPeople(val roomId: RoomId) : NavTarget

View file

@ -18,10 +18,12 @@ import io.element.android.libraries.di.SessionScope
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint { class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint {
override fun createNode( override fun createNode(
isSpace: Boolean,
parentNode: Node, parentNode: Node,
buildContext: BuildContext, buildContext: BuildContext,
callback: CreateRoomEntryPoint.Callback, callback: CreateRoomEntryPoint.Callback,
): Node { ): Node {
return parentNode.createNode<CreateRoomFlowNode>(buildContext, listOf(callback)) val inputs = CreateRoomFlowNode.Inputs(isSpace)
return parentNode.createNode<CreateRoomFlowNode>(buildContext, listOf(inputs, callback))
} }
} }

View file

@ -8,6 +8,7 @@
package io.element.android.features.createroom.impl.configureroom package io.element.android.features.createroom.impl.configureroom
import android.os.Parcelable
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.bumble.appyx.core.lifecycle.subscribe import com.bumble.appyx.core.lifecycle.subscribe
@ -18,23 +19,35 @@ import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedInject import dev.zacsweers.metro.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.annotations.ContributesNode import io.element.android.annotations.ContributesNode
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.callback
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
@AssistedInject @AssistedInject
class ConfigureRoomNode( class ConfigureRoomNode(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: ConfigureRoomPresenter, presenterFactory: ConfigureRoomPresenter.Factory,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
) : Node(buildContext, plugins = plugins) { ) : Node(buildContext, plugins = plugins) {
interface Callback : Plugin { interface Callback : Plugin {
fun onCreateRoomSuccess(roomId: RoomId) fun onCreateRoomSuccess(roomId: RoomId)
} }
@Parcelize
data class Inputs(
val isSpace: Boolean,
) : NodeInputs, Parcelable
private val inputs = inputs<Inputs>()
private val presenter = presenterFactory.create(inputs.isSpace)
init { init {
lifecycle.subscribe( lifecycle.subscribe(
onResume = { onResume = {

View file

@ -19,7 +19,9 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.core.net.toUri import androidx.core.net.toUri
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.AssistedInject
import im.vector.app.features.analytics.plan.CreatedRoom import im.vector.app.features.analytics.plan.CreatedRoom
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
@ -40,7 +42,7 @@ import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidityEf
import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediapickers.api.PickerProvider
import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider import io.element.android.libraries.mediaupload.api.MediaOptimizationConfigProvider
import io.element.android.libraries.mediaupload.api.MediaPreProcessor import io.element.android.libraries.mediaupload.api.MediaPreProcessor
import io.element.android.libraries.permissions.api.PermissionsEvents import io.element.android.libraries.permissions.api.PermissionsEvent
import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.permissions.api.PermissionsPresenter
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
@ -49,8 +51,9 @@ import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import kotlin.jvm.optionals.getOrDefault import kotlin.jvm.optionals.getOrDefault
@Inject @AssistedInject
class ConfigureRoomPresenter( class ConfigureRoomPresenter(
@Assisted private val isSpace: Boolean,
private val dataStore: CreateRoomConfigStore, private val dataStore: CreateRoomConfigStore,
private val matrixClient: MatrixClient, private val matrixClient: MatrixClient,
private val mediaPickerProvider: PickerProvider, private val mediaPickerProvider: PickerProvider,
@ -61,13 +64,22 @@ class ConfigureRoomPresenter(
private val roomAliasHelper: RoomAliasHelper, private val roomAliasHelper: RoomAliasHelper,
private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider, private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider,
) : Presenter<ConfigureRoomState> { ) : Presenter<ConfigureRoomState> {
@AssistedFactory
interface Factory {
fun create(isSpace: Boolean): ConfigureRoomPresenter
}
private val cameraPermissionPresenter: PermissionsPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA) private val cameraPermissionPresenter: PermissionsPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA)
private var pendingPermissionRequest = false private var pendingPermissionRequest = false
init {
dataStore.setIsSpace(isSpace)
}
@Composable @Composable
override fun present(): ConfigureRoomState { override fun present(): ConfigureRoomState {
val cameraPermissionState = cameraPermissionPresenter.present() val cameraPermissionState = cameraPermissionPresenter.present()
val createRoomConfig by dataStore.getCreateRoomConfigFlow().collectAsState(CreateRoomConfig()) val createRoomConfig by dataStore.getCreateRoomConfigFlow().collectAsState()
val homeserverName = remember { matrixClient.userIdServerName() } val homeserverName = remember { matrixClient.userIdServerName() }
val isKnockFeatureEnabled by remember { val isKnockFeatureEnabled by remember {
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock)
@ -132,7 +144,7 @@ class ConfigureRoomPresenter(
cameraPhotoPicker.launch() cameraPhotoPicker.launch()
} else { } else {
pendingPermissionRequest = true pendingPermissionRequest = true
cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions) cameraPermissionState.eventSink(PermissionsEvent.RequestPermissions)
} }
AvatarAction.Remove -> dataStore.setAvatarUri(uri = null) AvatarAction.Remove -> dataStore.setAvatarUri(uri = null)
} }
@ -171,7 +183,8 @@ class ConfigureRoomPresenter(
preset = RoomPreset.PUBLIC_CHAT, preset = RoomPreset.PUBLIC_CHAT,
invite = config.invites.map { it.userId }, invite = config.invites.map { it.userId },
avatar = avatarUrl, avatar = avatarUrl,
roomAliasName = config.roomVisibility.roomAddress() roomAliasName = config.roomVisibility.roomAddress(),
isSpace = isSpace,
) )
} else { } else {
CreateRoomParameters( CreateRoomParameters(
@ -184,6 +197,7 @@ class ConfigureRoomPresenter(
preset = RoomPreset.PRIVATE_CHAT, preset = RoomPreset.PRIVATE_CHAT,
invite = config.invites.map { it.userId }, invite = config.invites.map { it.userId },
avatar = avatarUrl, avatar = avatarUrl,
isSpace = isSpace,
) )
} }
matrixClient.createRoom(params) matrixClient.createRoom(params)

View file

@ -78,6 +78,18 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
), ),
roomAddressValidity = RoomAddressValidity.Valid, roomAddressValidity = RoomAddressValidity.Valid,
), ),
aConfigureRoomState(
config = CreateRoomConfig(
isSpace = true,
roomName = "Space 101",
topic = "Space topic for this space when the text goes onto multiple lines and is really long, there shouldnt be more than 3 lines",
roomVisibility = RoomVisibilityState.Public(
roomAddress = RoomAddress.AutoFilled("Space-101"),
roomAccess = RoomAccess.Anyone,
),
),
roomAddressValidity = RoomAddressValidity.Valid,
),
) )
} }

View file

@ -8,15 +8,16 @@
package io.element.android.features.createroom.impl.configureroom package io.element.android.features.createroom.impl.configureroom
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectableGroup import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
@ -27,10 +28,9 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -41,15 +41,18 @@ import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtomSize import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtomSize
import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionView
import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.avatar.AvatarType
import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.icons.CompoundDrawables
import io.element.android.libraries.designsystem.modifiers.clearFocusOnTap import io.element.android.libraries.designsystem.modifiers.clearFocusOnTap
import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.ListItem
import io.element.android.libraries.designsystem.theme.components.ListSectionHeader
import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text 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.TextButton
@ -57,10 +60,12 @@ import io.element.android.libraries.designsystem.theme.components.TextField
import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
import io.element.android.libraries.matrix.ui.components.UnsavedAvatar import io.element.android.libraries.matrix.ui.components.AvatarPickerState
import io.element.android.libraries.matrix.ui.components.AvatarPickerView
import io.element.android.libraries.matrix.ui.room.address.RoomAddressField import io.element.android.libraries.matrix.ui.room.address.RoomAddressField
import io.element.android.libraries.permissions.api.PermissionsView import io.element.android.libraries.permissions.api.PermissionsView
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlin.jvm.optionals.getOrNull
@Composable @Composable
fun ConfigureRoomView( fun ConfigureRoomView(
@ -69,6 +74,7 @@ fun ConfigureRoomView(
onCreateRoomSuccess: (RoomId) -> Unit, onCreateRoomSuccess: (RoomId) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val isSpace = state.config.isSpace
val focusManager = LocalFocusManager.current val focusManager = LocalFocusManager.current
val isAvatarActionsSheetVisible = remember { mutableStateOf(false) } val isAvatarActionsSheetVisible = remember { mutableStateOf(false) }
@ -81,6 +87,7 @@ fun ConfigureRoomView(
modifier = modifier.clearFocusOnTap(focusManager), modifier = modifier.clearFocusOnTap(focusManager),
topBar = { topBar = {
ConfigureRoomToolbar( ConfigureRoomToolbar(
isSpace = isSpace,
isNextActionEnabled = state.isValid, isNextActionEnabled = state.isValid,
onBackClick = onBackClick, onBackClick = onBackClick,
onNextClick = { onNextClick = {
@ -96,9 +103,10 @@ fun ConfigureRoomView(
.imePadding() .imePadding()
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
.consumeWindowInsets(padding), .consumeWindowInsets(padding),
verticalArrangement = Arrangement.spacedBy(24.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
) { ) {
RoomNameWithAvatar( RoomNameWithAvatar(
isSpace = isSpace,
modifier = Modifier.padding(horizontal = 16.dp), modifier = Modifier.padding(horizontal = 16.dp),
avatarUri = state.config.avatarUri, avatarUri = state.config.avatarUri,
roomName = state.config.roomName.orEmpty(), roomName = state.config.roomName.orEmpty(),
@ -110,37 +118,35 @@ fun ConfigureRoomView(
topic = state.config.topic.orEmpty(), topic = state.config.topic.orEmpty(),
onTopicChange = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) }, onTopicChange = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) },
) )
RoomVisibilityOptions(
RoomVisibilityAndAccessOptions(
selected = when (state.config.roomVisibility) { selected = when (state.config.roomVisibility) {
is RoomVisibilityState.Private -> RoomVisibilityItem.Private is RoomVisibilityState.Private -> RoomVisibilityItem.Private
is RoomVisibilityState.Public -> RoomVisibilityItem.Public is RoomVisibilityState.Public -> when (state.config.roomVisibility.roomAccess) {
RoomAccess.Knocking -> RoomVisibilityItem.AskToJoin
RoomAccess.Anyone -> RoomVisibilityItem.Public
}
}, },
isKnockingEnabled = state.isKnockFeatureEnabled,
onOptionClick = { onOptionClick = {
focusManager.clearFocus() focusManager.clearFocus()
state.eventSink(ConfigureRoomEvents.RoomVisibilityChanged(it)) state.eventSink(ConfigureRoomEvents.RoomVisibilityChanged(it))
}, },
) )
if (state.config.roomVisibility is RoomVisibilityState.Public && state.isKnockFeatureEnabled) {
RoomAccessOptions( if (state.config.roomVisibility !is RoomVisibilityState.Private) {
selected = when (state.config.roomVisibility.roomAccess) { Column {
RoomAccess.Anyone -> RoomAccessItem.Anyone ListSectionHeader(title = stringResource(R.string.screen_create_room_room_address_section_title))
RoomAccess.Knocking -> RoomAccessItem.AskToJoin RoomAddressField(
}, modifier = Modifier.padding(horizontal = 16.dp),
onOptionClick = { address = state.config.roomVisibility.roomAddress().getOrNull().orEmpty(),
focusManager.clearFocus() homeserverName = state.homeserverName,
state.eventSink(ConfigureRoomEvents.RoomAccessChanged(it)) addressValidity = state.roomAddressValidity,
}, onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) },
) label = null,
RoomAddressField( supportingText = stringResource(R.string.screen_create_room_room_address_section_footer),
modifier = Modifier.padding(horizontal = 16.dp), )
address = state.config.roomVisibility.roomAddress.value, }
homeserverName = state.homeserverName,
addressValidity = state.roomAddressValidity,
onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) },
label = stringResource(R.string.screen_create_room_room_address_section_title),
supportingText = stringResource(R.string.screen_create_room_room_address_section_footer),
)
Spacer(Modifier)
} }
} }
} }
@ -156,11 +162,11 @@ fun ConfigureRoomView(
async = state.createRoomAction, async = state.createRoomAction,
progressDialog = { progressDialog = {
AsyncActionViewDefaults.ProgressDialog( AsyncActionViewDefaults.ProgressDialog(
progressText = stringResource(CommonStrings.common_creating_room), progressText = stringResource(if (isSpace) CommonStrings.common_creating_space else CommonStrings.common_creating_room),
) )
}, },
onSuccess = { onCreateRoomSuccess(it) }, onSuccess = { onCreateRoomSuccess(it) },
errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) }, errorMessage = { stringResource(if (isSpace) R.string.screen_create_room_error_creating_space else R.string.screen_create_room_error_creating_room) },
onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom) }, onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom) },
onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) }, onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) },
) )
@ -173,12 +179,13 @@ fun ConfigureRoomView(
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun ConfigureRoomToolbar( private fun ConfigureRoomToolbar(
isSpace: Boolean,
isNextActionEnabled: Boolean, isNextActionEnabled: Boolean,
onBackClick: () -> Unit, onBackClick: () -> Unit,
onNextClick: () -> Unit, onNextClick: () -> Unit,
) { ) {
TopAppBar( TopAppBar(
titleStr = stringResource(R.string.screen_create_room_title), titleStr = stringResource(if (isSpace) R.string.screen_create_room_new_space_title else R.string.screen_create_room_new_room_title),
navigationIcon = { BackButton(onClick = onBackClick) }, navigationIcon = { BackButton(onClick = onBackClick) },
actions = { actions = {
TextButton( TextButton(
@ -192,6 +199,7 @@ private fun ConfigureRoomToolbar(
@Composable @Composable
private fun RoomNameWithAvatar( private fun RoomNameWithAvatar(
isSpace: Boolean,
avatarUri: String?, avatarUri: String?,
roomName: String, roomName: String,
onAvatarClick: () -> Unit, onAvatarClick: () -> Unit,
@ -203,25 +211,33 @@ private fun RoomNameWithAvatar(
horizontalArrangement = Arrangement.spacedBy(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
val a11yAvatar = stringResource(CommonStrings.a11y_room_avatar) Box(
UnsavedAvatar( modifier = Modifier.padding(end = 8.dp).size(AvatarSize.EditRoomDetails.dp),
avatarUri = avatarUri, contentAlignment = Alignment.Center,
avatarSize = AvatarSize.EditRoomDetails, ) {
avatarType = AvatarType.Room(), val avatarState = remember(avatarUri) {
modifier = Modifier if (avatarUri != null) {
.clickable( AvatarPickerState.Selected(
onClick = onAvatarClick, avatarData = AvatarData(id = "#", name = null, url = avatarUri, size = AvatarSize.EditRoomDetails),
onClickLabel = stringResource(CommonStrings.action_open_context_menu), type = if (isSpace) AvatarType.Space() else AvatarType.Room(),
) )
.clearAndSetSemantics { } else {
contentDescription = a11yAvatar val containerSize = 48.dp
}, val padding = PaddingValues((AvatarSize.EditRoomDetails.dp - containerSize) / 2)
) AvatarPickerState.Pick(buttonSize = 48.dp, iconSize = 24.dp, externalPadding = padding)
}
}
AvatarPickerView(
state = avatarState,
onClick = onAvatarClick,
)
}
TextField( TextField(
label = stringResource(R.string.screen_create_room_room_name_label), modifier = Modifier.padding(bottom = 18.dp),
label = stringResource(CommonStrings.common_name),
value = roomName, value = roomName,
placeholder = stringResource(CommonStrings.common_room_name_placeholder), placeholder = stringResource(R.string.screen_create_room_name_placeholder),
singleLine = true, singleLine = true,
onValueChange = onChangeRoomName, onValueChange = onChangeRoomName,
) )
@ -240,7 +256,7 @@ private fun RoomTopic(
value = topic, value = topic,
onValueChange = onTopicChange, onValueChange = onTopicChange,
maxLines = 3, maxLines = 3,
supportingText = stringResource(CommonStrings.common_topic_placeholder), placeholder = stringResource(R.string.screen_create_room_topic_placeholder),
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Sentences, capitalization = KeyboardCapitalization.Sentences,
), ),
@ -256,38 +272,58 @@ private fun ConfigureRoomOptions(
Column( Column(
modifier = modifier.selectableGroup() modifier = modifier.selectableGroup()
) { ) {
Text( ListSectionHeader(title = title)
text = title,
style = ElementTheme.typography.fontBodyLgMedium,
color = ElementTheme.colors.textPrimary,
modifier = Modifier.padding(horizontal = 16.dp),
)
content() content()
} }
} }
@Composable @Composable
private fun RoomVisibilityOptions( private fun RoomVisibilityAndAccessOptions(
selected: RoomVisibilityItem, selected: RoomVisibilityItem,
isKnockingEnabled: Boolean,
onOptionClick: (RoomVisibilityItem) -> Unit, onOptionClick: (RoomVisibilityItem) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
ConfigureRoomOptions( ConfigureRoomOptions(
title = stringResource(R.string.screen_create_room_room_visibility_section_title), title = stringResource(R.string.screen_create_room_room_access_section_title),
modifier = modifier, modifier = modifier,
) { ) {
RoomVisibilityItem.entries.forEach { item -> RoomVisibilityItem.entries.forEach { item ->
if (item == RoomVisibilityItem.AskToJoin && !isKnockingEnabled) {
return@forEach
}
val isSelected = item == selected val isSelected = item == selected
ListItem( ListItem(
leadingContent = ListItemContent.Custom { leadingContent = ListItemContent.Custom {
RoundedIconAtom( RoundedIconAtom(
size = RoundedIconAtomSize.Big, size = RoundedIconAtomSize.Big,
resourceId = item.icon, resourceId = when (item) {
RoomVisibilityItem.Public -> CompoundDrawables.ic_compound_public
RoomVisibilityItem.AskToJoin -> CompoundDrawables.ic_compound_user_add
RoomVisibilityItem.Private -> CompoundDrawables.ic_compound_lock
},
tint = if (isSelected) ElementTheme.colors.iconPrimary else ElementTheme.colors.iconSecondary, tint = if (isSelected) ElementTheme.colors.iconPrimary else ElementTheme.colors.iconSecondary,
backgroundTint = Color.Transparent,
) )
}, },
headlineContent = { Text(text = stringResource(item.title)) }, headlineContent = {
supportingContent = { Text(text = stringResource(item.description)) }, val title = when (item) {
RoomVisibilityItem.Public -> stringResource(R.string.screen_create_room_public_option_title)
RoomVisibilityItem.AskToJoin -> stringResource(R.string.screen_create_room_room_access_section_knocking_option_title)
RoomVisibilityItem.Private -> stringResource(R.string.screen_create_room_private_option_title)
}
Text(text = title)
},
supportingContent = {
// TODO handle description of items in a certain space/org
val description = when (item) {
RoomVisibilityItem.Public -> stringResource(R.string.screen_create_room_public_option_short_description)
RoomVisibilityItem.AskToJoin -> stringResource(R.string.screen_create_room_room_access_section_knocking_option_description)
RoomVisibilityItem.Private -> stringResource(R.string.screen_create_room_private_option_description)
}
Text(text = description)
},
trailingContent = ListItemContent.RadioButton(selected = isSelected), trailingContent = ListItemContent.RadioButton(selected = isSelected),
onClick = { onOptionClick(item) }, onClick = { onOptionClick(item) },
) )
@ -295,27 +331,6 @@ private fun RoomVisibilityOptions(
} }
} }
@Composable
private fun RoomAccessOptions(
selected: RoomAccessItem,
onOptionClick: (RoomAccessItem) -> Unit,
modifier: Modifier = Modifier,
) {
ConfigureRoomOptions(
title = stringResource(R.string.screen_create_room_room_access_section_header),
modifier = modifier,
) {
RoomAccessItem.entries.forEach { item ->
ListItem(
headlineContent = { Text(text = stringResource(item.title)) },
supportingContent = { Text(text = stringResource(item.description)) },
trailingContent = ListItemContent.RadioButton(selected = item == selected),
onClick = { onOptionClick(item) },
)
}
}
}
@PreviewWithLargeHeight @PreviewWithLargeHeight
@Composable @Composable
internal fun ConfigureRoomViewLightPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = internal fun ConfigureRoomViewLightPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) =

View file

@ -13,6 +13,7 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
data class CreateRoomConfig( data class CreateRoomConfig(
val isSpace: Boolean = false,
val roomName: String? = null, val roomName: String? = null,
val topic: String? = null, val topic: String? = null,
val avatarUri: String? = null, val avatarUri: String? = null,

View file

@ -72,11 +72,11 @@ class CreateRoomConfigStore(
config.copy( config.copy(
roomVisibility = when (visibility) { roomVisibility = when (visibility) {
RoomVisibilityItem.Private -> RoomVisibilityState.Private RoomVisibilityItem.Private -> RoomVisibilityState.Private
RoomVisibilityItem.Public -> { RoomVisibilityItem.Public, RoomVisibilityItem.AskToJoin -> {
val roomAliasName = roomAliasHelper.roomAliasNameFromRoomDisplayName(config.roomName.orEmpty()) val roomAliasName = roomAliasHelper.roomAliasNameFromRoomDisplayName(config.roomName.orEmpty())
RoomVisibilityState.Public( RoomVisibilityState.Public(
roomAddress = RoomAddress.AutoFilled(roomAliasName), roomAddress = RoomAddress.AutoFilled(roomAliasName),
roomAccess = RoomAccess.Anyone, roomAccess = if (visibility == RoomVisibilityItem.AskToJoin) RoomAccess.Knocking else RoomAccess.Anyone,
) )
} }
} }
@ -114,6 +114,12 @@ class CreateRoomConfigStore(
} }
} }
fun setIsSpace(isSpace: Boolean) {
createRoomConfigFlow.getAndUpdate { config ->
config.copy(isSpace = isSpace)
}
}
fun clearCachedData() { fun clearCachedData() {
cachedAvatarUri = null cachedAvatarUri = null
} }

View file

@ -8,19 +8,7 @@
package io.element.android.features.createroom.impl.configureroom package io.element.android.features.createroom.impl.configureroom
import androidx.annotation.StringRes enum class RoomAccessItem {
import io.element.android.features.createroom.impl.R Anyone,
AskToJoin,
enum class RoomAccessItem(
@StringRes val title: Int,
@StringRes val description: Int
) {
Anyone(
title = R.string.screen_create_room_room_access_section_anyone_option_title,
description = R.string.screen_create_room_room_access_section_anyone_option_description,
),
AskToJoin(
title = R.string.screen_create_room_room_access_section_knocking_option_title,
description = R.string.screen_create_room_room_access_section_knocking_option_description,
),
} }

View file

@ -8,24 +8,8 @@
package io.element.android.features.createroom.impl.configureroom package io.element.android.features.createroom.impl.configureroom
import androidx.annotation.DrawableRes enum class RoomVisibilityItem {
import androidx.annotation.StringRes Public,
import io.element.android.features.createroom.impl.R AskToJoin,
import io.element.android.libraries.designsystem.icons.CompoundDrawables Private
enum class RoomVisibilityItem(
@DrawableRes val icon: Int,
@StringRes val title: Int,
@StringRes val description: Int
) {
Private(
icon = CompoundDrawables.ic_compound_lock,
title = R.string.screen_create_room_private_option_title,
description = R.string.screen_create_room_private_option_description,
),
Public(
icon = CompoundDrawables.ic_compound_public,
title = R.string.screen_create_room_public_option_title,
description = R.string.screen_create_room_public_option_description,
)
} }

View file

@ -4,14 +4,10 @@
<string name="screen_create_room_add_people_title">"Запрасіць карыстальнікаў"</string> <string name="screen_create_room_add_people_title">"Запрасіць карыстальнікаў"</string>
<string name="screen_create_room_error_creating_room">"Пры стварэнні пакоя адбылася памылка"</string> <string name="screen_create_room_error_creating_room">"Пры стварэнні пакоя адбылася памылка"</string>
<string name="screen_create_room_private_option_description">"Толькі запрошаныя людзі могуць атрымаць доступ да гэтага пакоя. Усе паведамленні абаронены end-to-end шыфраваннем."</string> <string name="screen_create_room_private_option_description">"Толькі запрошаныя людзі могуць атрымаць доступ да гэтага пакоя. Усе паведамленні абаронены end-to-end шыфраваннем."</string>
<string name="screen_create_room_private_option_title">"Прыватны пакой"</string>
<string name="screen_create_room_public_option_description">"Любы можа знайсці гэты пакой. <string name="screen_create_room_public_option_description">"Любы можа знайсці гэты пакой.
Вы можаце змяніць гэта ў любы час у наладах пакоя."</string> Вы можаце змяніць гэта ў любы час у наладах пакоя."</string>
<string name="screen_create_room_public_option_title">"Публічны пакой"</string> <string name="screen_create_room_public_option_title">"Публічны пакой (для ўсіх)"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Хто заўгодна"</string>
<string name="screen_create_room_room_access_section_header">"Доступ у пакой"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Папрасіце далучыцца"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Папрасіце далучыцца"</string>
<string name="screen_create_room_room_name_label">"Назва пакоя"</string> <string name="screen_create_room_room_access_section_public_option_title">"Хто заўгодна"</string>
<string name="screen_create_room_title">"Стварыце пакой"</string>
<string name="screen_create_room_topic_label">"Тэма (неабавязкова)"</string> <string name="screen_create_room_topic_label">"Тэма (неабавязкова)"</string>
</resources> </resources>

View file

@ -4,15 +4,12 @@
<string name="screen_create_room_add_people_title">"Поканване на хора"</string> <string name="screen_create_room_add_people_title">"Поканване на хора"</string>
<string name="screen_create_room_error_creating_room">"Възникна грешка при създаването на стаята"</string> <string name="screen_create_room_error_creating_room">"Възникна грешка при създаването на стаята"</string>
<string name="screen_create_room_private_option_description">"Само поканени хора имат достъп до тази стая. Всички съобщения са шифровани от край до край."</string> <string name="screen_create_room_private_option_description">"Само поканени хора имат достъп до тази стая. Всички съобщения са шифровани от край до край."</string>
<string name="screen_create_room_private_option_title">"Частна стая"</string>
<string name="screen_create_room_public_option_description">"Всеки може да намери тази стая. <string name="screen_create_room_public_option_description">"Всеки може да намери тази стая.
Можете да промените това по всяко време в настройките на стаята."</string> Можете да промените това по всяко време в настройките на стаята."</string>
<string name="screen_create_room_public_option_title">"Общодостъпна стая"</string> <string name="screen_create_room_public_option_title">"Публична стая (всеки)"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Всеки може да се присъедини към тази стая"</string> <string name="screen_create_room_room_access_section_public_option_description">"Всеки може да се присъедини към тази стая"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Всеки"</string> <string name="screen_create_room_room_access_section_public_option_title">"Всеки"</string>
<string name="screen_create_room_room_address_section_footer">"За да бъде тази стая видима в директорията на общодостъпните стаи, ще ви е необходим адрес на стаята."</string> <string name="screen_create_room_room_address_section_footer">"За да бъде тази стая видима в директорията на общодостъпните стаи, ще ви е необходим адрес на стаята."</string>
<string name="screen_create_room_room_name_label">"Име на стаята"</string>
<string name="screen_create_room_room_visibility_section_title">"Видимост на стаята"</string> <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_create_room_topic_label">"Тема за разговор (незадължително)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Pozvat přátele"</string> <string name="screen_create_room_add_people_title">"Pozvat přátele"</string>
<string name="screen_create_room_error_creating_room">"Při vytváření místnosti došlo k chybě"</string> <string name="screen_create_room_error_creating_room">"Při vytváření místnosti došlo k chybě"</string>
<string name="screen_create_room_private_option_description">"Do této místnosti mají přístup pouze pozvaní lidé. Všechny zprávy jsou koncově šifrovány."</string> <string name="screen_create_room_private_option_description">"Do této místnosti mají přístup pouze pozvaní lidé. Všechny zprávy jsou koncově šifrovány."</string>
<string name="screen_create_room_private_option_title">"Soukromá místnost"</string>
<string name="screen_create_room_public_option_description">"Tuto místnost může najít kdokoli. <string name="screen_create_room_public_option_description">"Tuto místnost může najít kdokoli.
To můžete kdykoli změnit v nastavení místnosti."</string> To můžete kdykoli změnit v nastavení místnosti."</string>
<string name="screen_create_room_public_option_title">"Veřejná místnost"</string> <string name="screen_create_room_public_option_title">"Veřejná místnost"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Do této místnosti může vstoupit kdokoli"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Kdokoliv"</string>
<string name="screen_create_room_room_access_section_header">"Přístup do místnosti"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Požádat o připojení"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Požádat o připojení"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Do této místnosti může vstoupit kdokoli"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Kdokoliv"</string>
<string name="screen_create_room_room_address_section_footer">"Aby byla tato místnost viditelná v adresáři veřejných místností, budete potřebovat adresu místnosti."</string> <string name="screen_create_room_room_address_section_footer">"Aby byla tato místnost viditelná v adresáři veřejných místností, budete potřebovat adresu místnosti."</string>
<string name="screen_create_room_room_address_section_title">"Adresa místnosti"</string> <string name="screen_create_room_room_address_section_title">"Adresa místnosti"</string>
<string name="screen_create_room_room_name_label">"Název místnosti"</string>
<string name="screen_create_room_room_visibility_section_title">"Viditelnost 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_create_room_topic_label">"Téma (nepovinné)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Gwahodd pobl"</string> <string name="screen_create_room_add_people_title">"Gwahodd pobl"</string>
<string name="screen_create_room_error_creating_room">"Bu gwall wrth greu\'r ystafell"</string> <string name="screen_create_room_error_creating_room">"Bu gwall wrth greu\'r ystafell"</string>
<string name="screen_create_room_private_option_description">"Dim ond pobl wahoddwyd all gael mynediad i\'r ystafell hon. Mae pob neges wedi\'i hamgryptio o\'r dechrau i\'r diwedd."</string> <string name="screen_create_room_private_option_description">"Dim ond pobl wahoddwyd all gael mynediad i\'r ystafell hon. Mae pob neges wedi\'i hamgryptio o\'r dechrau i\'r diwedd."</string>
<string name="screen_create_room_private_option_title">"Ystafell breifat"</string>
<string name="screen_create_room_public_option_description">"Gall unrhyw un ddod o hyd i\'r ystafell hon. <string name="screen_create_room_public_option_description">"Gall unrhyw un ddod o hyd i\'r ystafell hon.
Gallwch newid hyn unrhyw bryd yng ngosodiadau ystafell."</string> Gallwch newid hyn unrhyw bryd yng ngosodiadau ystafell."</string>
<string name="screen_create_room_public_option_title">"Ystafell gyhoeddus"</string> <string name="screen_create_room_public_option_title">"Ystafell gyhoeddus"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Gall unrhyw un ymuno â\'r ystafell hon"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Unrhyw un"</string>
<string name="screen_create_room_room_access_section_header">"Mynediad i\'r Ystafell"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Gofyn i gael ymuno"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Gofyn i gael ymuno"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Gall unrhyw un ymuno â\'r ystafell hon"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Unrhyw un"</string>
<string name="screen_create_room_room_address_section_footer">"Er mwyn i\'r ystafell hon fod yn weladwy yn y cyfeiriadur ystafelloedd cyhoeddus, bydd angen cyfeiriad ystafell arnoch."</string> <string name="screen_create_room_room_address_section_footer">"Er mwyn i\'r ystafell hon fod yn weladwy yn y cyfeiriadur ystafelloedd cyhoeddus, bydd angen cyfeiriad ystafell arnoch."</string>
<string name="screen_create_room_room_address_section_title">"Cyfeiriad yr ystafell"</string> <string name="screen_create_room_room_address_section_title">"Cyfeiriad yr ystafell"</string>
<string name="screen_create_room_room_name_label">"Enw\'r ystafell"</string>
<string name="screen_create_room_room_visibility_section_title">"Gwelededd yr ystafell"</string> <string name="screen_create_room_room_visibility_section_title">"Gwelededd yr ystafell"</string>
<string name="screen_create_room_title">"Creu ystafell"</string>
<string name="screen_create_room_topic_label">"Pwnc (dewisol)"</string> <string name="screen_create_room_topic_label">"Pwnc (dewisol)"</string>
</resources> </resources>

View file

@ -4,18 +4,14 @@
<string name="screen_create_room_add_people_title">"Invitér andre"</string> <string name="screen_create_room_add_people_title">"Invitér andre"</string>
<string name="screen_create_room_error_creating_room">"Der opstod en fejl ved oprettelsen af rummet"</string> <string name="screen_create_room_error_creating_room">"Der opstod en fejl ved oprettelsen af rummet"</string>
<string name="screen_create_room_private_option_description">"Kun inviterede personer kan få adgang til dette rum. Alle meddelelser er ende-til-ende krypteret."</string> <string name="screen_create_room_private_option_description">"Kun inviterede personer kan få adgang til dette rum. Alle meddelelser er ende-til-ende krypteret."</string>
<string name="screen_create_room_private_option_title">"Privat rum"</string>
<string name="screen_create_room_public_option_description">"Alle kan finde dette rum. <string name="screen_create_room_public_option_description">"Alle kan finde dette rum.
Du kan ændre dette når som helst i rummets indstillinger."</string> Du kan ændre dette når som helst i rummets indstillinger."</string>
<string name="screen_create_room_public_option_title">"Offentligt rum"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Alle kan deltage i dette rum"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Enhver"</string>
<string name="screen_create_room_room_access_section_header">"Adgang til rummet"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Alle kan bede om at deltage i rummet, men en administrator eller en moderator skal acceptere anmodningen"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Alle kan bede om at deltage i rummet, men en administrator eller en moderator skal acceptere anmodningen"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Spørg om at deltage"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Spørg om at deltage"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Alle kan deltage i dette rum"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Enhver"</string>
<string name="screen_create_room_room_address_section_footer">"Hvis dette rum skal være synligt i det offentlige register, skal du bruge en rum-adresse."</string> <string name="screen_create_room_room_address_section_footer">"Hvis dette rum skal være synligt i det offentlige register, skal du bruge en rum-adresse."</string>
<string name="screen_create_room_room_name_label">"Navn på rum"</string> <string name="screen_create_room_room_address_section_title">"Rummets adresse"</string>
<string name="screen_create_room_room_visibility_section_title">"Rummets synlighed"</string> <string name="screen_create_room_room_visibility_section_title">"Rummets synlighed"</string>
<string name="screen_create_room_title">"Opret et rum"</string>
<string name="screen_create_room_topic_label">"Emne (valgfrit)"</string> <string name="screen_create_room_topic_label">"Emne (valgfrit)"</string>
</resources> </resources>

View file

@ -3,20 +3,26 @@
<string name="screen_create_room_action_create_room">"Neuer Chat"</string> <string name="screen_create_room_action_create_room">"Neuer Chat"</string>
<string name="screen_create_room_add_people_title">"Nutzer einladen"</string> <string name="screen_create_room_add_people_title">"Nutzer einladen"</string>
<string name="screen_create_room_error_creating_room">"Beim Erstellen des Chats ist ein Fehler aufgetreten"</string> <string name="screen_create_room_error_creating_room">"Beim Erstellen des Chats ist ein Fehler aufgetreten"</string>
<string name="screen_create_room_private_option_description">"Nur eingeladene Personen haben Zutritt zu diesem Chat. Alle Nachrichten sind Ende-zu-Ende verschlüsselt."</string> <string name="screen_create_room_error_creating_space">"Der Space konnte wegen eines unbekannten Fehlers nicht erstellt werden. Versuch\' es später nochmal."</string>
<string name="screen_create_room_private_option_title">"Privater Chat"</string> <string name="screen_create_room_name_placeholder">"Name hinzufügen…"</string>
<string name="screen_create_room_new_room_title">"Neuer Chat"</string>
<string name="screen_create_room_new_space_title">"Neuer Space"</string>
<string name="screen_create_room_private_option_description">"Nur eingeladene Personen haben Zutritt zu diesem Chat."</string>
<string name="screen_create_room_private_option_title">"Privat"</string>
<string name="screen_create_room_public_option_description">"Jeder kann diesen Chat finden. <string name="screen_create_room_public_option_description">"Jeder kann diesen Chat finden.
Du kannst dies jederzeit in den Einstellungen des Chats ändern."</string> Du kannst dies jederzeit in den Einstellungen des Chats ändern."</string>
<string name="screen_create_room_public_option_title">"Öffentlicher Chat"</string> <string name="screen_create_room_public_option_short_description">"Jeder kann beitreten."</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Jeder darf diesem Chat beitreten"</string> <string name="screen_create_room_public_option_title">"Öffentlicher Chatroom"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Jeder"</string>
<string name="screen_create_room_room_access_section_header">"Chat Zugang"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Jeder kann den Beitritt zum Chat erbitten, aber ein Admin oder Moderator muss die Anfrage akzeptieren."</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Jeder kann den Beitritt zum Chat erbitten, aber ein Admin oder Moderator muss die Anfrage akzeptieren."</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Beitritt beantragen"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Anfrage zum Beitritt zulassen"</string>
<string name="screen_create_room_room_address_section_footer">"Du benötigst eine Chat-Adresse, damit dieser Chat im öffentlichen Verzeichnis sichtbar ist."</string> <string name="screen_create_room_room_access_section_private_option_description">"Nur eingeladene Personen können beitreten."</string>
<string name="screen_create_room_room_address_section_title">"Chatroom Adresse"</string> <string name="screen_create_room_room_access_section_private_option_title">"Privat"</string>
<string name="screen_create_room_room_name_label">"Chat-Name"</string> <string name="screen_create_room_room_access_section_public_option_description">"Jeder darf diesem Chat beitreten."</string>
<string name="screen_create_room_room_access_section_public_option_title">"Jeder"</string>
<string name="screen_create_room_room_access_section_title">"Wer hat Zugang"</string>
<string name="screen_create_room_room_address_section_footer">"Du benötigst eine Adresse, um diesen Chat im öffentlichen Verzeichnis sichtbar zu machen."</string>
<string name="screen_create_room_room_address_section_title">"Adresse"</string>
<string name="screen_create_room_room_visibility_section_title">" Sichtbarkeit des Chats"</string> <string name="screen_create_room_room_visibility_section_title">" Sichtbarkeit des Chats"</string>
<string name="screen_create_room_title">"Chat erstellen"</string>
<string name="screen_create_room_topic_label">"Thema (optional)"</string> <string name="screen_create_room_topic_label">"Thema (optional)"</string>
<string name="screen_create_room_topic_placeholder">"Beschreibung hinzufügen…"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Πρόσκληση ατόμων"</string> <string name="screen_create_room_add_people_title">"Πρόσκληση ατόμων"</string>
<string name="screen_create_room_error_creating_room">"Προέκυψε σφάλμα κατά τη δημιουργία της αίθουσας"</string> <string name="screen_create_room_error_creating_room">"Προέκυψε σφάλμα κατά τη δημιουργία της αίθουσας"</string>
<string name="screen_create_room_private_option_description">"Μόνο τα άτομα που έχουν προσκληθεί μπορούν να έχουν πρόσβαση σε αυτή την αίθουσα. Όλα τα μηνύματα είναι κρυπτογραφημένα από άκρο σε άκρο."</string> <string name="screen_create_room_private_option_description">"Μόνο τα άτομα που έχουν προσκληθεί μπορούν να έχουν πρόσβαση σε αυτή την αίθουσα. Όλα τα μηνύματα είναι κρυπτογραφημένα από άκρο σε άκρο."</string>
<string name="screen_create_room_private_option_title">"Ιδιωτική αίθουσα"</string>
<string name="screen_create_room_public_option_description">"Ο καθένας μπορεί να βρει αυτή την αίθουσα. <string name="screen_create_room_public_option_description">"Ο καθένας μπορεί να βρει αυτή την αίθουσα.
Αυτό μπορείτε να το αλλάξετε ανά πάσα στιγμή στις ρυθμίσεις της αίθουσας."</string> Αυτό μπορείτε να το αλλάξετε ανά πάσα στιγμή στις ρυθμίσεις της αίθουσας."</string>
<string name="screen_create_room_public_option_title">"Δημόσια αίθουσα"</string> <string name="screen_create_room_public_option_title">"Δημόσιο δωμάτιο"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Οποιοσδήποτε μπορεί να συμμετάσχει σε αυτή την αίθουσα"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Οποιοσδήποτε"</string>
<string name="screen_create_room_room_access_section_header">"Πρόσβαση στην Αίθουσα"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή ένας συντονιστής θα πρέπει να αποδεχτεί το αίτημα"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή ένας συντονιστής θα πρέπει να αποδεχτεί το αίτημα"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Αίτημα συμμετοχής"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Αίτημα συμμετοχής"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Οποιοσδήποτε μπορεί να συμμετάσχει σε αυτή την αίθουσα"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Οποιοσδήποτε"</string>
<string name="screen_create_room_room_address_section_footer">"Για να είναι ορατή αυτή η αίθουσα στον δημόσιο κατάλογο αιθουσών, θα χρειαστείτε μια διεύθυνση αίθουσας."</string> <string name="screen_create_room_room_address_section_footer">"Για να είναι ορατή αυτή η αίθουσα στον δημόσιο κατάλογο αιθουσών, θα χρειαστείτε μια διεύθυνση αίθουσας."</string>
<string name="screen_create_room_room_address_section_title">"Διεύθυνση δωματίου"</string> <string name="screen_create_room_room_address_section_title">"Διεύθυνση δωματίου"</string>
<string name="screen_create_room_room_name_label">"Όνομα αίθουσας"</string>
<string name="screen_create_room_room_visibility_section_title">"Ορατότητα αίθουσας"</string> <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_create_room_topic_label">"Θέμα (προαιρετικό)"</string>
</resources> </resources>

View file

@ -4,18 +4,14 @@
<string name="screen_create_room_add_people_title">"Invitar personas"</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_error_creating_room">"Se ha producido un error al crear la sala"</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_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. <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> 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_public_option_title">"Sala pública (cualquiera)"</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_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_access_section_knocking_option_title">"Solicitud para unirse"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Cualquiera puede unirse a esta sala"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Cualquiera"</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_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_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_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_create_room_topic_label">"Tema (opcional)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Kutsu osalejaid"</string> <string name="screen_create_room_add_people_title">"Kutsu osalejaid"</string>
<string name="screen_create_room_error_creating_room">"Jututoa loomisel tekkis viga"</string> <string name="screen_create_room_error_creating_room">"Jututoa loomisel tekkis viga"</string>
<string name="screen_create_room_private_option_description">"Ligipääs siia jututuppa on vaid kutse alusel. Kõik sõnumid siin jututoas on läbivalt krüptitud."</string> <string name="screen_create_room_private_option_description">"Ligipääs siia jututuppa on vaid kutse alusel. Kõik sõnumid siin jututoas on läbivalt krüptitud."</string>
<string name="screen_create_room_private_option_title">"Privaatne jututuba"</string>
<string name="screen_create_room_public_option_description">"Kõik saavad seda jututuba leida. <string name="screen_create_room_public_option_description">"Kõik saavad seda jututuba leida.
Sa võid seda jututoa seadistustest alati muuta."</string> Sa võid seda jututoa seadistustest alati muuta."</string>
<string name="screen_create_room_public_option_title">"Avalik jututuba"</string> <string name="screen_create_room_public_option_title">"Avalik jututuba"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Kõik võivad selle jututoaga liituda"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Kõik"</string>
<string name="screen_create_room_room_access_section_header">"Ligipääs jututoale"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Kõik võivad paluda selle jututoaga liitumist, kuid peakasutaja või moderaator peavad selle kinnitama"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Kõik võivad paluda selle jututoaga liitumist, kuid peakasutaja või moderaator peavad selle kinnitama"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Küsi võimalust liitumiseks"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Küsi võimalust liitumiseks"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Kõik võivad selle jututoaga liituda"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Kõik kasutajad"</string>
<string name="screen_create_room_room_address_section_footer">"Selleks, et see jututuba oleks nähtav jututubade avalikus kataloogis, sa vajad jututoa aadressi."</string> <string name="screen_create_room_room_address_section_footer">"Selleks, et see jututuba oleks nähtav jututubade avalikus kataloogis, sa vajad jututoa aadressi."</string>
<string name="screen_create_room_room_address_section_title">"Jututoa aadress"</string> <string name="screen_create_room_room_address_section_title">"Jututoa aadress"</string>
<string name="screen_create_room_room_name_label">"Jututoa nimi"</string>
<string name="screen_create_room_room_visibility_section_title">"Jututoa nähtavus"</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_create_room_topic_label">"Teema (kui soovid lisada)"</string>
</resources> </resources>

View file

@ -4,16 +4,12 @@
<string name="screen_create_room_add_people_title">"Gonbidatu jendea"</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_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_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. <string name="screen_create_room_public_option_description">"Edonork aurki dezake gela hau.
Gelaren ezarpenetan aldatu dezakezu hobespena."</string> Gelaren ezarpenetan aldatu dezakezu hobespena."</string>
<string name="screen_create_room_public_option_title">"Gela publikoa"</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_public_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_public_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_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_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_create_room_topic_label">"Mintzagaia (aukerakoa)"</string>
</resources> </resources>

View file

@ -7,14 +7,11 @@
<string name="screen_create_room_private_option_title">"اتاق خصوصی"</string> <string name="screen_create_room_private_option_title">"اتاق خصوصی"</string>
<string name="screen_create_room_public_option_description">"هرکسی می‌تواند اتاق را بیابد. <string name="screen_create_room_public_option_description">"هرکسی می‌تواند اتاق را بیابد.
می‌توانید بعداً در تظیمات اتاق عوضش کنید."</string> می‌توانید بعداً در تظیمات اتاق عوضش کنید."</string>
<string name="screen_create_room_public_option_title">"اتاق عمومی"</string> <string name="screen_create_room_public_option_title">"اتاق عمومی (هرکسی)"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"هرکسی می‌تواند به این اتاق بپیوندد"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"هرکسی"</string>
<string name="screen_create_room_room_access_section_header">"دسترسی اتاق"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"درخواست دعوت"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"درخواست دعوت"</string>
<string name="screen_create_room_room_access_section_public_option_description">"هرکسی می‌تواند به این اتاق بپیوندد"</string>
<string name="screen_create_room_room_access_section_public_option_title">"هرکسی"</string>
<string name="screen_create_room_room_address_section_title">"نشانی اتاق"</string> <string name="screen_create_room_room_address_section_title">"نشانی اتاق"</string>
<string name="screen_create_room_room_name_label">"نام اتاق"</string>
<string name="screen_create_room_room_visibility_section_title">"نمایانی اتاق"</string> <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_create_room_topic_label">"موضوع (اختیاری)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Kutsu henkilöitä"</string> <string name="screen_create_room_add_people_title">"Kutsu henkilöitä"</string>
<string name="screen_create_room_error_creating_room">"Huoneen luomisessa tapahtui virhe"</string> <string name="screen_create_room_error_creating_room">"Huoneen luomisessa tapahtui virhe"</string>
<string name="screen_create_room_private_option_description">"Vain kutsutut henkilöt pääsevät tähän huoneeseen. Kaikki viestit ovat päästä päähän salattuja."</string> <string name="screen_create_room_private_option_description">"Vain kutsutut henkilöt pääsevät tähän huoneeseen. Kaikki viestit ovat päästä päähän salattuja."</string>
<string name="screen_create_room_private_option_title">"Yksityinen huone"</string>
<string name="screen_create_room_public_option_description">"Kuka tahansa voi löytää tämän huoneen. <string name="screen_create_room_public_option_description">"Kuka tahansa voi löytää tämän huoneen.
Voit muuttaa tämän milloin tahansa huoneen asetuksista."</string> Voit muuttaa tämän milloin tahansa huoneen asetuksista."</string>
<string name="screen_create_room_public_option_title">"Julkinen huone"</string> <string name="screen_create_room_public_option_title">"Julkinen huone"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Kuka tahansa voi liittyä tähän huoneeseen"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Kuka tahansa"</string>
<string name="screen_create_room_room_access_section_header">"Huoneeseen Pääsy"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Pyydä liittymistä"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Pyydä liittymistä"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Kuka tahansa voi liittyä tähän huoneeseen"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Kuka tahansa"</string>
<string name="screen_create_room_room_address_section_footer">"Jotta tämä huone näkyisi julkisessa huonehakemistossa, tarvitset huoneen osoitteen."</string> <string name="screen_create_room_room_address_section_footer">"Jotta tämä huone näkyisi julkisessa huonehakemistossa, tarvitset huoneen osoitteen."</string>
<string name="screen_create_room_room_address_section_title">"Huoneen osoite"</string> <string name="screen_create_room_room_address_section_title">"Huoneen osoite"</string>
<string name="screen_create_room_room_name_label">"Huoneen nimi"</string>
<string name="screen_create_room_room_visibility_section_title">"Huoneen näkyvyys"</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_create_room_topic_label">"Aihe (valinnainen)"</string>
</resources> </resources>

View file

@ -3,20 +3,26 @@
<string name="screen_create_room_action_create_room">"Nouveau salon"</string> <string name="screen_create_room_action_create_room">"Nouveau salon"</string>
<string name="screen_create_room_add_people_title">"Inviter des amis"</string> <string name="screen_create_room_add_people_title">"Inviter des amis"</string>
<string name="screen_create_room_error_creating_room">"Une erreur sest produite lors de la création du salon"</string> <string name="screen_create_room_error_creating_room">"Une erreur sest produite lors de la création du salon"</string>
<string name="screen_create_room_private_option_description">"Seules les personnes invitées peuvent accéder à ce salon. Tous les messages sont chiffrés de bout en bout."</string> <string name="screen_create_room_error_creating_space">"Lespace na pas pu être créé à cause dune erreur inconnue. Réessayez plus tard."</string>
<string name="screen_create_room_private_option_title">"Salon privé"</string> <string name="screen_create_room_name_placeholder">"Ajouter un nom…"</string>
<string name="screen_create_room_new_room_title">"Nouveau salon"</string>
<string name="screen_create_room_new_space_title">"Nouvel espace"</string>
<string name="screen_create_room_private_option_description">"Seules les personnes invitées peuvent joindre."</string>
<string name="screen_create_room_private_option_title">"Privé"</string>
<string name="screen_create_room_public_option_description">"Nimporte qui peut trouver ce salon. <string name="screen_create_room_public_option_description">"Nimporte qui peut trouver ce salon.
Vous pouvez modifier cela à tout moment dans les paramètres du salon."</string> Vous pouvez modifier cela à tout moment dans les paramètres du salon."</string>
<string name="screen_create_room_public_option_short_description">"Tout le monde peut joindre"</string>
<string name="screen_create_room_public_option_title">"Salon public"</string> <string name="screen_create_room_public_option_title">"Salon public"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Tout le monde peut rejoindre ce salon"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Tout le monde peut demander à joindre, mais un administrateur ou un modérateur devra accepter la demande"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Tout le monde"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Autoriser la demande à joindre"</string>
<string name="screen_create_room_room_access_section_header">"Accès au salon"</string> <string name="screen_create_room_room_access_section_private_option_description">"Seules les personnes invitées peuvent joindre."</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Tout le monde peut demander à rejoindre le salon, mais un administrateur ou un modérateur devra accepter la demande"</string> <string name="screen_create_room_room_access_section_private_option_title">"Privé"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Demander à rejoindre"</string> <string name="screen_create_room_room_access_section_public_option_description">"Tout le monde peut joindre"</string>
<string name="screen_create_room_room_address_section_footer">"Pour que ce salon soit visible dans le répertoire des salons publics, vous aurez besoin dune adresse de salon."</string> <string name="screen_create_room_room_access_section_public_option_title">"Tout le monde"</string>
<string name="screen_create_room_room_address_section_title">"Adresse du salon"</string> <string name="screen_create_room_room_access_section_title">"Qui a accès"</string>
<string name="screen_create_room_room_name_label">"Nom du salon"</string> <string name="screen_create_room_room_address_section_footer">"Vous aurez besoin dune adresse pour quil soit visible dans le répertoire public."</string>
<string name="screen_create_room_room_address_section_title">"Adresse"</string>
<string name="screen_create_room_room_visibility_section_title">"Visibilité 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_create_room_topic_label">"Sujet (facultatif)"</string>
<string name="screen_create_room_topic_placeholder">"Ajouter une description…"</string>
</resources> </resources>

View file

@ -0,0 +1,17 @@
<?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">"Nova soba"</string>
<string name="screen_create_room_add_people_title">"Pozovi osobe"</string>
<string name="screen_create_room_error_creating_room">"Došlo je do pogreške prilikom stvaranja sobe"</string>
<string name="screen_create_room_private_option_description">"Samo pozvane osobe mogu pristupiti ovoj sobi. Sve su poruke sveobuhvatno šifrirane."</string>
<string name="screen_create_room_public_option_description">"Svatko može pronaći ovu sobu.
To možete u svakom trenutku promijeniti u postavkama sobe."</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Svatko može zatražiti pridruživanje sobi, ali administrator ili moderator morat će prihvatiti zahtjev."</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Zatraži pridruživanje"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Svatko se može pridružiti ovoj sobi"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Svatko"</string>
<string name="screen_create_room_room_address_section_footer">"Da bi ova soba bila vidljiva u javnom direktoriju soba, trebat će vam adresa sobe."</string>
<string name="screen_create_room_room_address_section_title">"Adresa sobe"</string>
<string name="screen_create_room_room_visibility_section_title">"Vidljivost sobe"</string>
<string name="screen_create_room_topic_label">"Tema (neobavezno)"</string>
</resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Ismerősök meghívása"</string> <string name="screen_create_room_add_people_title">"Ismerősök meghívása"</string>
<string name="screen_create_room_error_creating_room">"Hiba történt a szoba létrehozásakor"</string> <string name="screen_create_room_error_creating_room">"Hiba történt a szoba létrehozásakor"</string>
<string name="screen_create_room_private_option_description">"Csak a meghívottak léphetnek be ebbe a szobába. Az összes üzenet végpontok közti titkosítással van védve."</string> <string name="screen_create_room_private_option_description">"Csak a meghívottak léphetnek be ebbe a szobába. Az összes üzenet végpontok közti titkosítással van védve."</string>
<string name="screen_create_room_private_option_title">"Privát szoba"</string>
<string name="screen_create_room_public_option_description">"Bárki megtalálhatja ezt a szobát. <string name="screen_create_room_public_option_description">"Bárki megtalálhatja ezt a szobát.
Ezt bármikor módosíthatja a szobabeállításokban."</string> Ezt bármikor módosíthatja a szobabeállításokban."</string>
<string name="screen_create_room_public_option_title">"Nyilvános szoba"</string> <string name="screen_create_room_public_option_title">"Nyilvános szoba"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Bárki csatlakozhat ehhez a szobához"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Bárki"</string>
<string name="screen_create_room_room_access_section_header">"Szobahozzáférés"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Bárki kérheti, hogy csatlakozzon a szobához, de egy adminisztrátornak vagy moderátornak el kell fogadnia a kérést"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Bárki kérheti, hogy csatlakozzon a szobához, de egy adminisztrátornak vagy moderátornak el kell fogadnia a kérést"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Csatlakozás kérése"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Csatlakozás kérése"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Bárki csatlakozhat ehhez a szobához"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Bárki"</string>
<string name="screen_create_room_room_address_section_footer">"Ahhoz, hogy ez a szoba látható legyen a nyilvános szobák címtárában, meg kell adnia a szoba címét."</string> <string name="screen_create_room_room_address_section_footer">"Ahhoz, hogy ez a szoba látható legyen a nyilvános szobák címtárában, meg kell adnia a szoba címét."</string>
<string name="screen_create_room_room_address_section_title">"Szoba címe"</string> <string name="screen_create_room_room_address_section_title">"Szoba címe"</string>
<string name="screen_create_room_room_name_label">"Szoba neve"</string>
<string name="screen_create_room_room_visibility_section_title">"Szoba láthatósága"</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_create_room_topic_label">"Téma (nem kötelező)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Undang orang-orang"</string> <string name="screen_create_room_add_people_title">"Undang orang-orang"</string>
<string name="screen_create_room_error_creating_room">"Terjadi kesalahan saat membuat ruangan"</string> <string name="screen_create_room_error_creating_room">"Terjadi kesalahan saat membuat ruangan"</string>
<string name="screen_create_room_private_option_description">"Hanya orang-orang yang diundang dapat mengakses ruangan ini. Semua pesan terenkripsi secara ujung ke ujung."</string> <string name="screen_create_room_private_option_description">"Hanya orang-orang yang diundang dapat mengakses ruangan ini. Semua pesan terenkripsi secara ujung ke ujung."</string>
<string name="screen_create_room_private_option_title">"Ruangan pribadi"</string>
<string name="screen_create_room_public_option_description">"Siapa pun dapat mencari ruangan ini. <string name="screen_create_room_public_option_description">"Siapa pun dapat mencari ruangan ini.
Anda dapat mengubah ini kapan pun dalam pengaturan ruangan."</string> Anda dapat mengubah ini kapan pun dalam pengaturan ruangan."</string>
<string name="screen_create_room_public_option_title">"Ruangan publik"</string> <string name="screen_create_room_public_option_title">"Ruangan publik"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Siapa pun dapat bergabung dengan ruangan ini"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Siapa pun"</string>
<string name="screen_create_room_room_access_section_header">"Akses Ruangan"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Minta untuk bergabung"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Minta untuk bergabung"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Siapa pun dapat bergabung dengan ruangan ini"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Siapa pun"</string>
<string name="screen_create_room_room_address_section_footer">"Supaya ruangan ini terlihat di direktori ruangan publik, Anda memerlukan alamat ruangan."</string> <string name="screen_create_room_room_address_section_footer">"Supaya ruangan ini terlihat di direktori ruangan publik, Anda memerlukan alamat ruangan."</string>
<string name="screen_create_room_room_address_section_title">"Alamat ruangan"</string> <string name="screen_create_room_room_address_section_title">"Alamat ruangan"</string>
<string name="screen_create_room_room_name_label">"Nama ruangan"</string>
<string name="screen_create_room_room_visibility_section_title">"Keterlihatan 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_create_room_topic_label">"Topik (opsional)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Invita persone"</string> <string name="screen_create_room_add_people_title">"Invita persone"</string>
<string name="screen_create_room_error_creating_room">"Si è verificato un errore durante la creazione della stanza"</string> <string name="screen_create_room_error_creating_room">"Si è verificato un errore durante la creazione della stanza"</string>
<string name="screen_create_room_private_option_description">"Solo le persone invitate possono accedere a questa stanza. Tutti i messaggi sono cifrati end-to-end."</string> <string name="screen_create_room_private_option_description">"Solo le persone invitate possono accedere a questa stanza. Tutti i messaggi sono cifrati end-to-end."</string>
<string name="screen_create_room_private_option_title">"Stanza privata"</string>
<string name="screen_create_room_public_option_description">"Chiunque può trovare questa stanza. <string name="screen_create_room_public_option_description">"Chiunque può trovare questa stanza.
Puoi modificarlo in qualsiasi momento nelle impostazioni della stanza."</string> Puoi modificarlo in qualsiasi momento nelle impostazioni della stanza."</string>
<string name="screen_create_room_public_option_title">"Stanza pubblica"</string> <string name="screen_create_room_public_option_title">"Stanza pubblica"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Chiunque può entrare in questa stanza"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Chiunque"</string>
<string name="screen_create_room_room_access_section_header">"Accesso alla stanza"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Chiedi di entrare"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Chiedi di entrare"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Chiunque può entrare in questa stanza"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Chiunque"</string>
<string name="screen_create_room_room_address_section_footer">"Affinché questa stanza sia visibile nell\'elenco delle stanze pubbliche, è necessario un indirizzo della stanza."</string> <string name="screen_create_room_room_address_section_footer">"Affinché questa stanza sia visibile nell\'elenco delle stanze pubbliche, è necessario un indirizzo della stanza."</string>
<string name="screen_create_room_room_address_section_title">"Indirizzo della stanza"</string> <string name="screen_create_room_room_address_section_title">"Indirizzo della stanza"</string>
<string name="screen_create_room_room_name_label">"Nome stanza"</string>
<string name="screen_create_room_room_visibility_section_title">"Visibilità 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_create_room_topic_label">"Argomento (facoltativo)"</string>
</resources> </resources>

View file

@ -4,10 +4,8 @@
<string name="screen_create_room_add_people_title">"ხალხის მოწვევა"</string> <string name="screen_create_room_add_people_title">"ხალხის მოწვევა"</string>
<string name="screen_create_room_error_creating_room">"ოთახის შექმნისას შეცდომა მოხდა"</string> <string name="screen_create_room_error_creating_room">"ოთახის შექმნისას შეცდომა მოხდა"</string>
<string name="screen_create_room_private_option_description">"ამ ოთახში შეტყობინებები დაშიფრულია. შემდგომ დაშიფვრის გამორთვა შეუძლებელია."</string> <string name="screen_create_room_private_option_description">"ამ ოთახში შეტყობინებები დაშიფრულია. შემდგომ დაშიფვრის გამორთვა შეუძლებელია."</string>
<string name="screen_create_room_private_option_title">"კერძო ოთახი"</string>
<string name="screen_create_room_public_option_description">"ყველას ამ ოთახის მოძებნა შეუძლია. <string name="screen_create_room_public_option_description">"ყველას ამ ოთახის მოძებნა შეუძლია.
თქვენ ნებისმიერ დროს შეგიძლიათ ამის შეცვლა ოთახის პარამეტრებში."</string> თქვენ ნებისმიერ დროს შეგიძლიათ ამის შეცვლა ოთახის პარამეტრებში."</string>
<string name="screen_create_room_room_name_label">"ოთახის სახელი"</string> <string name="screen_create_room_public_option_title">"საჯარო ოთახი"</string>
<string name="screen_create_room_title">"ოთახის შექმნა"</string>
<string name="screen_create_room_topic_label">"თემა (სურვილისამებრ)"</string> <string name="screen_create_room_topic_label">"თემა (სურვილისამებრ)"</string>
</resources> </resources>

View file

@ -4,18 +4,14 @@
<string name="screen_create_room_add_people_title">"사람 초대하기"</string> <string name="screen_create_room_add_people_title">"사람 초대하기"</string>
<string name="screen_create_room_error_creating_room">"방을 생성하던 중 오류가 발생했어요"</string> <string name="screen_create_room_error_creating_room">"방을 생성하던 중 오류가 발생했어요"</string>
<string name="screen_create_room_private_option_description">"초대받은 사람만 이 방에 액세스할 수 있습니다. 모든 메시지는 종단 간 암호화됩니다."</string> <string name="screen_create_room_private_option_description">"초대받은 사람만 이 방에 액세스할 수 있습니다. 모든 메시지는 종단 간 암호화됩니다."</string>
<string name="screen_create_room_private_option_title">"비공개 방"</string>
<string name="screen_create_room_public_option_description">"누구나 이 방을 찾을 수 있습니다. <string name="screen_create_room_public_option_description">"누구나 이 방을 찾을 수 있습니다.
방 설정에서 언제든지 변경할 수 있습니다."</string> 방 설정에서 언제든지 변경할 수 있습니다."</string>
<string name="screen_create_room_public_option_title">"공개 방"</string> <string name="screen_create_room_public_option_title">"공개 방 (모두)"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"누구나 이 방에 참여할 수 있습니다."</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"누구나"</string>
<string name="screen_create_room_room_access_section_header">"방 액세스"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다."</string> <string name="screen_create_room_room_access_section_knocking_option_description">"누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다."</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"참가 요청"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"참가 요청"</string>
<string name="screen_create_room_room_access_section_public_option_description">"누구나 이 방에 참여할 수 있습니다."</string>
<string name="screen_create_room_room_access_section_public_option_title">"누구나"</string>
<string name="screen_create_room_room_address_section_footer">"이 방이 공개 방 디렉토리에 표시되려면 방 주소가 필요합니다."</string> <string name="screen_create_room_room_address_section_footer">"이 방이 공개 방 디렉토리에 표시되려면 방 주소가 필요합니다."</string>
<string name="screen_create_room_room_name_label">"방 이름"</string>
<string name="screen_create_room_room_visibility_section_title">"방 표시 여부"</string> <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_create_room_topic_label">"주제 (선택)"</string>
</resources> </resources>

View file

@ -4,10 +4,7 @@
<string name="screen_create_room_add_people_title">"Pakviesti žmonių"</string> <string name="screen_create_room_add_people_title">"Pakviesti žmonių"</string>
<string name="screen_create_room_error_creating_room">"Kuriant kambarį įvyko klaida"</string> <string name="screen_create_room_error_creating_room">"Kuriant kambarį įvyko klaida"</string>
<string name="screen_create_room_private_option_description">"Į šį kambarį gali patekti tik pakviesti žmonės. Visi pranešimai yra užšifruoti nuo pradžios iki galo."</string> <string name="screen_create_room_private_option_description">"Į šį kambarį gali patekti tik pakviesti žmonės. Visi pranešimai yra užšifruoti nuo pradžios iki galo."</string>
<string name="screen_create_room_private_option_title">"Privatus kambarys"</string>
<string name="screen_create_room_public_option_description">"Bet kas gali rasti šį kambarį. <string name="screen_create_room_public_option_description">"Bet kas gali rasti šį kambarį.
Tai galite bet kada pakeisti kambario nustatymuose."</string> Tai galite bet kada pakeisti kambario nustatymuose."</string>
<string name="screen_create_room_room_name_label">"Kambario pavadinimas"</string>
<string name="screen_create_room_title">"Kurti kambarį"</string>
<string name="screen_create_room_topic_label">"Tema (nebūtina)"</string> <string name="screen_create_room_topic_label">"Tema (nebūtina)"</string>
</resources> </resources>

View file

@ -4,18 +4,15 @@
<string name="screen_create_room_add_people_title">"Inviter folk"</string> <string name="screen_create_room_add_people_title">"Inviter folk"</string>
<string name="screen_create_room_error_creating_room">"Det oppsto en feil under opprettelsen av rommet"</string> <string name="screen_create_room_error_creating_room">"Det oppsto en feil under opprettelsen av rommet"</string>
<string name="screen_create_room_private_option_description">"Bare inviterte personer har tilgang til dette rommet. Alle meldinger er ende-til-ende-kryptert."</string> <string name="screen_create_room_private_option_description">"Bare inviterte personer har tilgang til dette rommet. Alle meldinger er ende-til-ende-kryptert."</string>
<string name="screen_create_room_private_option_title">"Privat rom"</string>
<string name="screen_create_room_public_option_description">"Alle kan finne dette rommet. <string name="screen_create_room_public_option_description">"Alle kan finne dette rommet.
Du kan endre dette når som helst i rominnstillingene."</string> 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_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_anyone_option_title">"Alle"</string>
<string name="screen_create_room_room_access_section_header">"Tilgang til rom"</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_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_access_section_knocking_option_title">"Be om å bli med"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Alle kan bli med i dette rommet"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Alle"</string>
<string name="screen_create_room_room_address_section_footer">"For at dette rommet skal være synlig i den offentlige romkatalogen, trenger du en romadresse."</string> <string name="screen_create_room_room_address_section_footer">"For at dette rommet skal være synlig i den offentlige romkatalogen, trenger du en romadresse."</string>
<string name="screen_create_room_room_name_label">"Romnavn"</string> <string name="screen_create_room_room_address_section_title">"Romadresse"</string>
<string name="screen_create_room_room_visibility_section_title">"Romsynlighet"</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_create_room_topic_label">"Emne (valgfritt)"</string>
</resources> </resources>

View file

@ -4,16 +4,12 @@
<string name="screen_create_room_add_people_title">"Mensen uitnodigen"</string> <string name="screen_create_room_add_people_title">"Mensen uitnodigen"</string>
<string name="screen_create_room_error_creating_room">"Er is een fout opgetreden bij het aanmaken van de kamer"</string> <string name="screen_create_room_error_creating_room">"Er is een fout opgetreden bij het aanmaken van de kamer"</string>
<string name="screen_create_room_private_option_description">"Alleen uitgenodigde personen hebben toegang tot deze kamer. Alle berichten zijn end-to-end versleuteld."</string> <string name="screen_create_room_private_option_description">"Alleen uitgenodigde personen hebben toegang tot deze kamer. Alle berichten zijn end-to-end versleuteld."</string>
<string name="screen_create_room_private_option_title">"Privé kamer"</string>
<string name="screen_create_room_public_option_description">"Iedereen kan deze kamer vinden. <string name="screen_create_room_public_option_description">"Iedereen kan deze kamer vinden.
Je kunt dit op elk gewenst moment wijzigen in de kamerinstellingen."</string> Je kunt dit op elk gewenst moment wijzigen in de kamerinstellingen."</string>
<string name="screen_create_room_public_option_title">"Openbare kamer"</string> <string name="screen_create_room_public_option_title">"Openbare kamer"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Iedereen kan toetreden tot deze kamer"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Iedereen"</string>
<string name="screen_create_room_room_access_section_header">"Toegang tot de kamer"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Iedereen kan vragen om toe te treden tot de kamer, maar een beheerder of moderator moet het verzoek accepteren"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Iedereen kan vragen om toe te treden tot de kamer, maar een beheerder of moderator moet het verzoek accepteren"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Vraag om toe te treden"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Vraag om toe te treden"</string>
<string name="screen_create_room_room_name_label">"Naam van de kamer"</string> <string name="screen_create_room_room_access_section_public_option_description">"Iedereen kan toetreden tot deze kamer"</string>
<string name="screen_create_room_title">"Creëer een kamer"</string> <string name="screen_create_room_room_access_section_public_option_title">"Iedereen"</string>
<string name="screen_create_room_topic_label">"Onderwerp (optioneel)"</string> <string name="screen_create_room_topic_label">"Onderwerp (optioneel)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Zaproś znajomych"</string> <string name="screen_create_room_add_people_title">"Zaproś znajomych"</string>
<string name="screen_create_room_error_creating_room">"Wystąpił błąd w trakcie tworzenia pokoju"</string> <string name="screen_create_room_error_creating_room">"Wystąpił błąd w trakcie tworzenia pokoju"</string>
<string name="screen_create_room_private_option_description">"Tylko zaproszone osoby mogą dołączyć do tego pokoju. Wszystkie wiadomości są szyfrowane end-to-end."</string> <string name="screen_create_room_private_option_description">"Tylko zaproszone osoby mogą dołączyć do tego pokoju. Wszystkie wiadomości są szyfrowane end-to-end."</string>
<string name="screen_create_room_private_option_title">"Pokój prywatny"</string>
<string name="screen_create_room_public_option_description">"Każdy może znaleźć ten pokój. <string name="screen_create_room_public_option_description">"Każdy może znaleźć ten pokój.
Możesz to zmienić w ustawieniach pokoju."</string> Możesz to zmienić w ustawieniach pokoju."</string>
<string name="screen_create_room_public_option_title">"Pokój publiczny"</string> <string name="screen_create_room_public_option_title">"Pokój publiczny"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Każdy może dołączyć do tego pokoju"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Wszyscy"</string>
<string name="screen_create_room_room_access_section_header">"Dostęp do pokoju"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić prośbę"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić prośbę"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Poproś o dołączenie"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Poproś o dołączenie"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Każdy może dołączyć do tego pokoju"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Wszyscy"</string>
<string name="screen_create_room_room_address_section_footer">"Aby ten pokój był widoczny w katalogu pomieszczeń publicznych, będziesz potrzebował adres pokoju."</string> <string name="screen_create_room_room_address_section_footer">"Aby ten pokój był widoczny w katalogu pomieszczeń publicznych, będziesz potrzebował adres pokoju."</string>
<string name="screen_create_room_room_address_section_title">"Adres pokoju"</string> <string name="screen_create_room_room_address_section_title">"Adres pokoju"</string>
<string name="screen_create_room_room_name_label">"Nazwa pokoju"</string>
<string name="screen_create_room_room_visibility_section_title">"Widoczność pomieszczenia"</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_create_room_topic_label">"Temat (opcjonalnie)"</string>
</resources> </resources>

View file

@ -3,20 +3,21 @@
<string name="screen_create_room_action_create_room">"Nova sala"</string> <string name="screen_create_room_action_create_room">"Nova sala"</string>
<string name="screen_create_room_add_people_title">"Convidar pessoas"</string> <string name="screen_create_room_add_people_title">"Convidar pessoas"</string>
<string name="screen_create_room_error_creating_room">"Ocorreu um erro ao criar a sala"</string> <string name="screen_create_room_error_creating_room">"Ocorreu um erro ao criar a sala"</string>
<string name="screen_create_room_private_option_description">"Apenas as pessoas convidadas podem entrar nesta sala. Todas as mensagens são criptografadas de ponta a ponta."</string> <string name="screen_create_room_error_creating_space">"O espaço não pôde ser criado por conta de um erro desconhecido. Tente novamente mais tarde."</string>
<string name="screen_create_room_private_option_title">"Sala privada"</string> <string name="screen_create_room_new_space_title">"Novo espaço"</string>
<string name="screen_create_room_private_option_description">"Apenas pessoas convidadas podem entrar."</string>
<string name="screen_create_room_private_option_title">"Privada"</string>
<string name="screen_create_room_public_option_description">"Qualquer um pode encontrar esta sala. <string name="screen_create_room_public_option_description">"Qualquer um pode encontrar esta sala.
Você pode mudar isso a qualquer momento nas configurações da sala."</string> Você pode mudar isso a qualquer momento nas configurações da sala."</string>
<string name="screen_create_room_public_option_title">"Sala pública"</string> <string name="screen_create_room_public_option_short_description">"Qualquer um pode entrar."</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Qualquer pessoa pode entrar nesta sala"</string> <string name="screen_create_room_public_option_title">"Publica"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Qualquer pessoa"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Qualquer um pode pedir para entrar, mas um administrador ou moderador deve aceitar a solicitação"</string>
<string name="screen_create_room_room_access_section_header">"Acesso à sala"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá de aceitar a solicitação"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Pedir para entrar"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Pedir para entrar"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Qualquer um pode entrar."</string>
<string name="screen_create_room_room_access_section_public_option_title">"Qualquer pessoa"</string>
<string name="screen_create_room_room_access_section_title">"Quem tem acesso"</string>
<string name="screen_create_room_room_address_section_footer">"Para que esta sala fique visível no diretório público de salas, você precisará de um endereço de sala."</string> <string name="screen_create_room_room_address_section_footer">"Para que esta sala fique visível no diretório público de salas, você precisará de um endereço de sala."</string>
<string name="screen_create_room_room_address_section_title">"Endereço da sala"</string> <string name="screen_create_room_room_address_section_title">"Endereço da sala"</string>
<string name="screen_create_room_room_name_label">"Nome da sala"</string>
<string name="screen_create_room_room_visibility_section_title">"Visibilidade 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">"Tópico (opcional)"</string> <string name="screen_create_room_topic_label">"Tópico (opcional)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Convidar pessoas"</string> <string name="screen_create_room_add_people_title">"Convidar pessoas"</string>
<string name="screen_create_room_error_creating_room">"Ocorreu um erro ao criar a sala"</string> <string name="screen_create_room_error_creating_room">"Ocorreu um erro ao criar a sala"</string>
<string name="screen_create_room_private_option_description">"Apenas as pessoas convidadas podem aceder a esta sala. Todas as mensagens são cifradas ponta-a-ponta."</string> <string name="screen_create_room_private_option_description">"Apenas as pessoas convidadas podem aceder a esta sala. Todas as mensagens são cifradas ponta-a-ponta."</string>
<string name="screen_create_room_private_option_title">"Sala privada"</string>
<string name="screen_create_room_public_option_description">"Qualquer um pode encontrar esta sala. <string name="screen_create_room_public_option_description">"Qualquer um pode encontrar esta sala.
Pode alterar esta opção nas definições da sala."</string> Pode alterar esta opção nas definições da sala."</string>
<string name="screen_create_room_public_option_title">"Sala pública"</string> <string name="screen_create_room_public_option_title">"Sala pública"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Qualquer pessoa pode entrar nesta sala"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Qualquer pessoa"</string>
<string name="screen_create_room_room_access_section_header">"Acesso à sala"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou um moderador terá de aceitar o pedido"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou um moderador terá de aceitar o pedido"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Pedir para participar"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Pedir para participar"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Qualquer pessoa pode entrar nesta sala"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Qualquer pessoa"</string>
<string name="screen_create_room_room_address_section_footer">"Para que esta sala seja visível no diretório público de salas, precisas de um endereço de sala."</string> <string name="screen_create_room_room_address_section_footer">"Para que esta sala seja visível no diretório público de salas, precisas de um endereço de sala."</string>
<string name="screen_create_room_room_address_section_title">"Endereço da sala"</string> <string name="screen_create_room_room_address_section_title">"Endereço da sala"</string>
<string name="screen_create_room_room_name_label">"Nome da sala"</string>
<string name="screen_create_room_room_visibility_section_title">"Visibilidade 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_create_room_topic_label">"Descrição (opcional)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Invitați prieteni"</string> <string name="screen_create_room_add_people_title">"Invitați prieteni"</string>
<string name="screen_create_room_error_creating_room">"A apărut o eroare la crearea camerei"</string> <string name="screen_create_room_error_creating_room">"A apărut o eroare la crearea camerei"</string>
<string name="screen_create_room_private_option_description">"Doar persoanele invitate pot accesa această cameră. Toate mesajele sunt criptate end-to-end."</string> <string name="screen_create_room_private_option_description">"Doar persoanele invitate pot accesa această cameră. Toate mesajele sunt criptate end-to-end."</string>
<string name="screen_create_room_private_option_title">"Cameră privată"</string>
<string name="screen_create_room_public_option_description">"Oricine poate găsi această cameră. <string name="screen_create_room_public_option_description">"Oricine poate găsi această cameră.
Puteți modifica acest lucru oricând în setări."</string> Puteți modifica acest lucru oricând în setări."</string>
<string name="screen_create_room_public_option_title">"Cameră publică"</string> <string name="screen_create_room_public_option_title">"Cameră publică"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Oricine se poate alătura acestei camere"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Oricine"</string>
<string name="screen_create_room_room_access_section_header">"Acces la cameră"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Oricine poate cere să se alăture camerei, dar un administrator sau un moderator va trebui să accepte cererea"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Oricine poate cere să se alăture camerei, dar un administrator sau un moderator va trebui să accepte cererea"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Cereți să vă alăturați"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Cereți să vă alăturați"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Oricine se poate alătura acestei camere"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Oricine"</string>
<string name="screen_create_room_room_address_section_footer">"Pentru ca această cameră să fie vizibilă în directorul de camere publice, veți avea nevoie de o adresă de cameră."</string> <string name="screen_create_room_room_address_section_footer">"Pentru ca această cameră să fie vizibilă în directorul de camere publice, veți avea nevoie de o adresă de cameră."</string>
<string name="screen_create_room_room_address_section_title">"Adresa camerei"</string> <string name="screen_create_room_room_address_section_title">"Adresa camerei"</string>
<string name="screen_create_room_room_name_label">"Numele camerei"</string>
<string name="screen_create_room_room_visibility_section_title">"Vizibilitatea camerei"</string> <string name="screen_create_room_room_visibility_section_title">"Vizibilitatea 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_create_room_topic_label">"Subiect (opțional)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Пригласить в комнату"</string> <string name="screen_create_room_add_people_title">"Пригласить в комнату"</string>
<string name="screen_create_room_error_creating_room">"Произошла ошибка при создании комнаты"</string> <string name="screen_create_room_error_creating_room">"Произошла ошибка при создании комнаты"</string>
<string name="screen_create_room_private_option_description">"Доступ в эту комнату имеют только приглашенные пользователи. Все сообщения защищены сквозным шифрованием."</string> <string name="screen_create_room_private_option_description">"Доступ в эту комнату имеют только приглашенные пользователи. Все сообщения защищены сквозным шифрованием."</string>
<string name="screen_create_room_private_option_title">"Частная комната"</string>
<string name="screen_create_room_public_option_description">"Любой желающий может найти эту комнату. <string name="screen_create_room_public_option_description">"Любой желающий может найти эту комнату.
Вы можете изменить это в любое время в настройках комнаты."</string> Вы можете изменить это в любое время в настройках комнаты."</string>
<string name="screen_create_room_public_option_title">"Общедоступная комната"</string> <string name="screen_create_room_public_option_title">"Общедоступная комната"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Любой желающий может присоединиться к этой комнате"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Любой"</string>
<string name="screen_create_room_room_access_section_header">"Доступ в комнату"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Любой желающий может подать заявку на присоединение к комнате, но администратор или модератор должен будет принять запрос."</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Любой желающий может подать заявку на присоединение к комнате, но администратор или модератор должен будет принять запрос."</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Попросить присоединиться"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Попросить присоединиться"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Любой желающий может присоединиться к этой комнате"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Любой"</string>
<string name="screen_create_room_room_address_section_footer">"Чтобы эта комната была видна в каталоге общедоступных, вам необходим ее адрес"</string> <string name="screen_create_room_room_address_section_footer">"Чтобы эта комната была видна в каталоге общедоступных, вам необходим ее адрес"</string>
<string name="screen_create_room_room_address_section_title">"Адрес комнаты"</string> <string name="screen_create_room_room_address_section_title">"Адрес комнаты"</string>
<string name="screen_create_room_room_name_label">"Название комнаты"</string>
<string name="screen_create_room_room_visibility_section_title">"Видимость комнаты"</string> <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_create_room_topic_label">"Тема (необязательно)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Pozvať ľudí"</string> <string name="screen_create_room_add_people_title">"Pozvať ľudí"</string>
<string name="screen_create_room_error_creating_room">"Pri vytváraní miestnosti došlo k chybe"</string> <string name="screen_create_room_error_creating_room">"Pri vytváraní miestnosti došlo k chybe"</string>
<string name="screen_create_room_private_option_description">"Do tejto miestnosti majú prístup iba pozvaní ľudia. Všetky správy sú end-to-end šifrované."</string> <string name="screen_create_room_private_option_description">"Do tejto miestnosti majú prístup iba pozvaní ľudia. Všetky správy sú end-to-end šifrované."</string>
<string name="screen_create_room_private_option_title">"Súkromná miestnosť"</string>
<string name="screen_create_room_public_option_description">"Túto miestnosť môže nájsť ktokoľvek. <string name="screen_create_room_public_option_description">"Túto miestnosť môže nájsť ktokoľvek.
Môžete to kedykoľvek zmeniť v nastaveniach miestnosti."</string> Môžete to kedykoľvek zmeniť v nastaveniach miestnosti."</string>
<string name="screen_create_room_public_option_title">"Verejná miestnosť"</string> <string name="screen_create_room_public_option_title">"Verejná miestnosť"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Do tejto miestnosti sa môže pripojiť ktokoľvek"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Ktokoľvek"</string>
<string name="screen_create_room_room_access_section_header">"Prístup do miestnosti"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Ktokoľvek môže požiadať o pripojenie sa k miestnosti, ale administrátor alebo moderátor bude musieť žiadosť schváliť"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Ktokoľvek môže požiadať o pripojenie sa k miestnosti, ale administrátor alebo moderátor bude musieť žiadosť schváliť"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Požiadať o pripojenie"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Požiadať o pripojenie"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Do tejto miestnosti sa môže pripojiť ktokoľvek"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Ktokoľvek"</string>
<string name="screen_create_room_room_address_section_footer">"Aby bola táto miestnosť viditeľná v adresári verejných miestností, budete potrebovať adresu miestnosti."</string> <string name="screen_create_room_room_address_section_footer">"Aby bola táto miestnosť viditeľná v adresári verejných miestností, budete potrebovať adresu miestnosti."</string>
<string name="screen_create_room_room_address_section_title">"Adresa miestnosti"</string> <string name="screen_create_room_room_address_section_title">"Adresa miestnosti"</string>
<string name="screen_create_room_room_name_label">"Názov miestnosti"</string>
<string name="screen_create_room_room_visibility_section_title">"Viditeľnosť 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_create_room_topic_label">"Téma (voliteľné)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Bjud in personer"</string> <string name="screen_create_room_add_people_title">"Bjud in personer"</string>
<string name="screen_create_room_error_creating_room">"Ett fel uppstod när rummet skapades"</string> <string name="screen_create_room_error_creating_room">"Ett fel uppstod när rummet skapades"</string>
<string name="screen_create_room_private_option_description">"Endast inbjudna personer har tillgång till detta rum. Alla meddelanden är totalsträckskrypterade."</string> <string name="screen_create_room_private_option_description">"Endast inbjudna personer har tillgång till detta rum. Alla meddelanden är totalsträckskrypterade."</string>
<string name="screen_create_room_private_option_title">"Privat rum"</string>
<string name="screen_create_room_public_option_description">"Vem som helst kan hitta det här rummet. <string name="screen_create_room_public_option_description">"Vem som helst kan hitta det här rummet.
Du kan ändra detta när som helst i rumsinställningarna."</string> Du kan ändra detta när som helst i rumsinställningarna."</string>
<string name="screen_create_room_public_option_title">"Offentligt rum"</string> <string name="screen_create_room_public_option_title">"Offentligt rum"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Vem som helst kan gå med i det här rummet"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Vem som helst"</string>
<string name="screen_create_room_room_access_section_header">"Rumsåtkomst"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Vem som helst kan be om att gå med i rummet men en administratör eller en moderator måste acceptera begäran"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Vem som helst kan be om att gå med i rummet men en administratör eller en moderator måste acceptera begäran"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Be om att gå med"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Be om att gå med"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Vem som helst kan gå med i det här rummet"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Vem som helst"</string>
<string name="screen_create_room_room_address_section_footer">"För att detta rum ska vara synligt i den allmänna rumskatalogen behöver du en rumsadress."</string> <string name="screen_create_room_room_address_section_footer">"För att detta rum ska vara synligt i den allmänna rumskatalogen behöver du en rumsadress."</string>
<string name="screen_create_room_room_address_section_title">"Rumsadress"</string> <string name="screen_create_room_room_address_section_title">"Rumsadress"</string>
<string name="screen_create_room_room_name_label">"Rumsnamn"</string>
<string name="screen_create_room_room_visibility_section_title">"Rumssynlighet"</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_create_room_topic_label">"Ämne (valfritt)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"İnsanları davet et"</string> <string name="screen_create_room_add_people_title">"İnsanları davet et"</string>
<string name="screen_create_room_error_creating_room">"Oda oluşturulurken bir hata oluştu"</string> <string name="screen_create_room_error_creating_room">"Oda oluşturulurken bir hata oluştu"</string>
<string name="screen_create_room_private_option_description">"Bu odaya yalnızca davet edilen kişiler erişebilir. Tüm mesajlar uçtan uca şifrelenir."</string> <string name="screen_create_room_private_option_description">"Bu odaya yalnızca davet edilen kişiler erişebilir. Tüm mesajlar uçtan uca şifrelenir."</string>
<string name="screen_create_room_private_option_title">"Özel oda"</string>
<string name="screen_create_room_public_option_description">"Bu odayı herkes bulabilir. <string name="screen_create_room_public_option_description">"Bu odayı herkes bulabilir.
Bunu istediğiniz zaman oda ayarlarından değiştirebilirsiniz."</string> Bunu istediğiniz zaman oda ayarlarından değiştirebilirsiniz."</string>
<string name="screen_create_room_public_option_title">"Herkese açık oda"</string> <string name="screen_create_room_public_option_title">"Herkese açık oda"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Bu odaya herkes katılabilir"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Herkes"</string>
<string name="screen_create_room_room_access_section_header">"Oda Erişimi"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Herkes odaya katılmayı isteyebilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekecektir"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Herkes odaya katılmayı isteyebilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekecektir"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Katılmak için sor"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Katılmak için sor"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Bu odaya herkes katılabilir"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Herkes"</string>
<string name="screen_create_room_room_address_section_footer">"Bu odanın genel oda dizininde görünür olması için bir oda adresine ihtiyacınız olacaktır."</string> <string name="screen_create_room_room_address_section_footer">"Bu odanın genel oda dizininde görünür olması için bir oda adresine ihtiyacınız olacaktır."</string>
<string name="screen_create_room_room_address_section_title">"Oda adresi"</string> <string name="screen_create_room_room_address_section_title">"Oda adresi"</string>
<string name="screen_create_room_room_name_label">"Oda adı"</string>
<string name="screen_create_room_room_visibility_section_title">"Oda görünürlüğü"</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_create_room_topic_label">"Konu (isteğe bağlı)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"Запросити людей"</string> <string name="screen_create_room_add_people_title">"Запросити людей"</string>
<string name="screen_create_room_error_creating_room">"Під час створення кімнати сталася помилка"</string> <string name="screen_create_room_error_creating_room">"Під час створення кімнати сталася помилка"</string>
<string name="screen_create_room_private_option_description">"Лише запрошені люди мають доступ до цієї кімнати. Усі повідомлення захищені наскрізним шифруванням."</string> <string name="screen_create_room_private_option_description">"Лише запрошені люди мають доступ до цієї кімнати. Усі повідомлення захищені наскрізним шифруванням."</string>
<string name="screen_create_room_private_option_title">"Приватна кімната (тільки за запрошенням)"</string>
<string name="screen_create_room_public_option_description">"Будь-хто може знайти цю кімнату. <string name="screen_create_room_public_option_description">"Будь-хто може знайти цю кімнату.
Ви можете змінити це в будь-який час у налаштуваннях кімнати."</string> Ви можете змінити це в будь-який час у налаштуваннях кімнати."</string>
<string name="screen_create_room_public_option_title">"Загальнодоступна кімната"</string> <string name="screen_create_room_public_option_title">"Публічна кімната"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Будь-хто може приєднатися до цієї кімнати"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Кожний"</string>
<string name="screen_create_room_room_access_section_header">"Доступ до кімнати"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Будь-хто може попросити приєднатися до кімнати, але адміністратор або модератор повинен буде прийняти запит"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Будь-хто може попросити приєднатися до кімнати, але адміністратор або модератор повинен буде прийняти запит"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Запросити приєднатися"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Запросити приєднатися"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Будь-хто може приєднатися до цієї кімнати"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Кожний"</string>
<string name="screen_create_room_room_address_section_footer">"Щоб цю кімнату було видно в каталозі загальнодоступних кімнат, вам знадобиться її адреса."</string> <string name="screen_create_room_room_address_section_footer">"Щоб цю кімнату було видно в каталозі загальнодоступних кімнат, вам знадобиться її адреса."</string>
<string name="screen_create_room_room_address_section_title">"Адреса кімнати"</string> <string name="screen_create_room_room_address_section_title">"Адреса кімнати"</string>
<string name="screen_create_room_room_name_label">"Назва кімнати"</string>
<string name="screen_create_room_room_visibility_section_title">"Видимість кімнати"</string> <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_create_room_topic_label">"Тема (необов\'язково)"</string>
</resources> </resources>

View file

@ -4,11 +4,7 @@
<string name="screen_create_room_add_people_title">"لوگوں کو مدعو کریں"</string> <string name="screen_create_room_add_people_title">"لوگوں کو مدعو کریں"</string>
<string name="screen_create_room_error_creating_room">"کمرہ تخلیق کرتے ہوئے ایک نقص واقع ہوا"</string> <string name="screen_create_room_error_creating_room">"کمرہ تخلیق کرتے ہوئے ایک نقص واقع ہوا"</string>
<string name="screen_create_room_private_option_description">"صرف مدعو لوگ ہی اس کمرے تک رسائی حاصل کر سکتے ہیں۔ تمام پیغامات آخر تا آخر مرموز کردہ ہیں۔"</string> <string name="screen_create_room_private_option_description">"صرف مدعو لوگ ہی اس کمرے تک رسائی حاصل کر سکتے ہیں۔ تمام پیغامات آخر تا آخر مرموز کردہ ہیں۔"</string>
<string name="screen_create_room_private_option_title">"نجی کمرہ"</string>
<string name="screen_create_room_public_option_description">"کوئی بھی یہ کمرہ ڈھونڈ سکتا ہے۔ <string name="screen_create_room_public_option_description">"کوئی بھی یہ کمرہ ڈھونڈ سکتا ہے۔
آپ اسے کمرے کی ترتیبات میں کسی بھی وقت تبدیل کرسکتے ہیں۔"</string> آپ اسے کمرے کی ترتیبات میں کسی بھی وقت تبدیل کرسکتے ہیں۔"</string>
<string name="screen_create_room_public_option_title">"عوامی کمرہ"</string>
<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_create_room_topic_label">"موضوع (اختیاری)"</string>
</resources> </resources>

View file

@ -4,18 +4,14 @@
<string name="screen_create_room_add_people_title">"Odamlarni taklif qiling"</string> <string name="screen_create_room_add_people_title">"Odamlarni taklif qiling"</string>
<string name="screen_create_room_error_creating_room">"Xonani yaratishda xatolik yuz berdi"</string> <string name="screen_create_room_error_creating_room">"Xonani yaratishda xatolik yuz berdi"</string>
<string name="screen_create_room_private_option_description">"Faqat taklif etilgan shaxslargina bu xonaga kira oladi. Barcha xabarlar boshdan-oxirigacha shifrlanadi."</string> <string name="screen_create_room_private_option_description">"Faqat taklif etilgan shaxslargina bu xonaga kira oladi. Barcha xabarlar boshdan-oxirigacha shifrlanadi."</string>
<string name="screen_create_room_private_option_title">"Shaxsiy xona"</string>
<string name="screen_create_room_public_option_description">"Bu xonani har kim topishi mumkin. <string name="screen_create_room_public_option_description">"Bu xonani har kim topishi mumkin.
Buni xona sozlamalaridan istalgan vaqtda oʻzgartirishingiz mumkin."</string> Buni xona sozlamalaridan istalgan vaqtda oʻzgartirishingiz mumkin."</string>
<string name="screen_create_room_public_option_title">"Jamoat xonasi"</string> <string name="screen_create_room_public_option_title">"Jamoat xonasi (har kim)"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Bu xonaga istalgan kishi qoshilishi mumkin"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Har kim"</string>
<string name="screen_create_room_room_access_section_header">"Xonaga kirish"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Xonaga qoshilishni istalgan kishi sorashi mumkin, lekin administrator yoki moderator sorovni qabul qilishi kerak"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Xonaga qoshilishni istalgan kishi sorashi mumkin, lekin administrator yoki moderator sorovni qabul qilishi kerak"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Qoshilishni sorang"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Qoshilishni sorang"</string>
<string name="screen_create_room_room_access_section_public_option_description">"Bu xonaga istalgan kishi qoshilishi mumkin"</string>
<string name="screen_create_room_room_access_section_public_option_title">"Har kim"</string>
<string name="screen_create_room_room_address_section_footer">"Ushbu xona ommaviy xonalar royxatida korinishi uchun sizga xona manzili kerak boladi."</string> <string name="screen_create_room_room_address_section_footer">"Ushbu xona ommaviy xonalar royxatida korinishi uchun sizga xona manzili kerak boladi."</string>
<string name="screen_create_room_room_name_label">"Xona nomi"</string>
<string name="screen_create_room_room_visibility_section_title">"Xonaning korinishi"</string> <string name="screen_create_room_room_visibility_section_title">"Xonaning korinishi"</string>
<string name="screen_create_room_title">"Xonani yaratish"</string>
<string name="screen_create_room_topic_label">"Mavzu (ixtiyoriy)"</string> <string name="screen_create_room_topic_label">"Mavzu (ixtiyoriy)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"邀請夥伴"</string> <string name="screen_create_room_add_people_title">"邀請夥伴"</string>
<string name="screen_create_room_error_creating_room">"建立聊天室時發生錯誤"</string> <string name="screen_create_room_error_creating_room">"建立聊天室時發生錯誤"</string>
<string name="screen_create_room_private_option_description">"僅被邀請的人才能存取此聊天室。所有訊息均會端到端加密。"</string> <string name="screen_create_room_private_option_description">"僅被邀請的人才能存取此聊天室。所有訊息均會端到端加密。"</string>
<string name="screen_create_room_private_option_title">"私密聊天室"</string>
<string name="screen_create_room_public_option_description">"任何人都可以找到此聊天室。 <string name="screen_create_room_public_option_description">"任何人都可以找到此聊天室。
您隨時都可以在聊天室設定中變更此設定。"</string> 您隨時都可以在聊天室設定中變更此設定。"</string>
<string name="screen_create_room_public_option_title">"公開的聊天室"</string> <string name="screen_create_room_public_option_title">"公開聊天室"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"任何人都可以加入此聊天室"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"任何人"</string>
<string name="screen_create_room_room_access_section_header">"聊天室存取權"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"任何人都可以要求加入聊天室,但管理員或版主必須接受該請求"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"任何人都可以要求加入聊天室,但管理員或版主必須接受該請求"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"要求加入"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"要求加入"</string>
<string name="screen_create_room_room_access_section_public_option_description">"任何人都可以加入此聊天室"</string>
<string name="screen_create_room_room_access_section_public_option_title">"任何人"</string>
<string name="screen_create_room_room_address_section_footer">"為了讓此聊天室在公開聊天室目錄中可見,您需要聊天室地址。"</string> <string name="screen_create_room_room_address_section_footer">"為了讓此聊天室在公開聊天室目錄中可見,您需要聊天室地址。"</string>
<string name="screen_create_room_room_address_section_title">"聊天室地址"</string> <string name="screen_create_room_room_address_section_title">"聊天室地址"</string>
<string name="screen_create_room_room_name_label">"聊天室名稱"</string>
<string name="screen_create_room_room_visibility_section_title">"聊天室能見度"</string> <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_create_room_topic_label">"主題(非必填)"</string>
</resources> </resources>

View file

@ -4,19 +4,15 @@
<string name="screen_create_room_add_people_title">"邀请朋友"</string> <string name="screen_create_room_add_people_title">"邀请朋友"</string>
<string name="screen_create_room_error_creating_room">"创建聊天室时出错"</string> <string name="screen_create_room_error_creating_room">"创建聊天室时出错"</string>
<string name="screen_create_room_private_option_description">"只有受邀用户才能访问此聊天室。所有消息均经过端到端加密。"</string> <string name="screen_create_room_private_option_description">"只有受邀用户才能访问此聊天室。所有消息均经过端到端加密。"</string>
<string name="screen_create_room_private_option_title">"私有聊天室"</string>
<string name="screen_create_room_public_option_description">"任何人都能找到此聊天室。 <string name="screen_create_room_public_option_description">"任何人都能找到此聊天室。
你可以随时在聊天室设置中更改。"</string> 你可以随时在聊天室设置中更改。"</string>
<string name="screen_create_room_public_option_title">"公共聊天室"</string> <string name="screen_create_room_public_option_title">"公开聊天室"</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"任何人都可以加入此房间"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"任何人"</string>
<string name="screen_create_room_room_access_section_header">"房间访问权限"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"任何人都可以请求加入房间,但必须由管理员或审核人接受"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"任何人都可以请求加入房间,但必须由管理员或审核人接受"</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"请求加入"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"请求加入"</string>
<string name="screen_create_room_room_access_section_public_option_description">"任何人都可以加入此房间"</string>
<string name="screen_create_room_room_access_section_public_option_title">"任何人"</string>
<string name="screen_create_room_room_address_section_footer">"要使该房间在公开房间目录中可见,您需要一个房间地址。"</string> <string name="screen_create_room_room_address_section_footer">"要使该房间在公开房间目录中可见,您需要一个房间地址。"</string>
<string name="screen_create_room_room_address_section_title">"房间地址"</string> <string name="screen_create_room_room_address_section_title">"房间地址"</string>
<string name="screen_create_room_room_name_label">"聊天室名称"</string>
<string name="screen_create_room_room_visibility_section_title">"房间可见性"</string> <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_create_room_topic_label">"主题(可选)"</string>
</resources> </resources>

View file

@ -3,20 +3,26 @@
<string name="screen_create_room_action_create_room">"New room"</string> <string name="screen_create_room_action_create_room">"New room"</string>
<string name="screen_create_room_add_people_title">"Invite people"</string> <string name="screen_create_room_add_people_title">"Invite people"</string>
<string name="screen_create_room_error_creating_room">"An error occurred when creating the room"</string> <string name="screen_create_room_error_creating_room">"An error occurred when creating the room"</string>
<string name="screen_create_room_private_option_description">"Only people invited can access this room. All messages are end-to-end encrypted."</string> <string name="screen_create_room_error_creating_space">"The space could not be created because of an unknown error. Try again later."</string>
<string name="screen_create_room_private_option_title">"Private room"</string> <string name="screen_create_room_name_placeholder">"Add name…"</string>
<string name="screen_create_room_new_room_title">"New room"</string>
<string name="screen_create_room_new_space_title">"New space"</string>
<string name="screen_create_room_private_option_description">"Only people invited can join."</string>
<string name="screen_create_room_private_option_title">"Private"</string>
<string name="screen_create_room_public_option_description">"Anyone can find this room. <string name="screen_create_room_public_option_description">"Anyone can find this room.
You can change this anytime in room settings."</string> You can change this anytime in room settings."</string>
<string name="screen_create_room_public_option_title">"Public room"</string> <string name="screen_create_room_public_option_short_description">"Anyone can join."</string>
<string name="screen_create_room_room_access_section_anyone_option_description">"Anyone can join this room"</string> <string name="screen_create_room_public_option_title">"Public"</string>
<string name="screen_create_room_room_access_section_anyone_option_title">"Anyone"</string> <string name="screen_create_room_room_access_section_knocking_option_description">"Anyone can ask to join but an administrator or a moderator must accept the request."</string>
<string name="screen_create_room_room_access_section_header">"Room Access"</string> <string name="screen_create_room_room_access_section_knocking_option_title">"Allow ask to join"</string>
<string name="screen_create_room_room_access_section_knocking_option_description">"Anyone can ask to join the room but an administrator or a moderator will have to accept the request"</string> <string name="screen_create_room_room_access_section_private_option_description">"Only people invited can join."</string>
<string name="screen_create_room_room_access_section_knocking_option_title">"Ask to join"</string> <string name="screen_create_room_room_access_section_private_option_title">"Private"</string>
<string name="screen_create_room_room_address_section_footer">"In order for this room to be visible in the public room directory, you will need a room address."</string> <string name="screen_create_room_room_access_section_public_option_description">"Anyone can join."</string>
<string name="screen_create_room_room_address_section_title">"Room address"</string> <string name="screen_create_room_room_access_section_public_option_title">"Public"</string>
<string name="screen_create_room_room_name_label">"Room name"</string> <string name="screen_create_room_room_access_section_title">"Who has access"</string>
<string name="screen_create_room_room_address_section_footer">"Youll need an address in order to make it visible in the public directory."</string>
<string name="screen_create_room_room_address_section_title">"Address"</string>
<string name="screen_create_room_room_visibility_section_title">"Room visibility"</string> <string name="screen_create_room_room_visibility_section_title">"Room visibility"</string>
<string name="screen_create_room_title">"Create a room"</string>
<string name="screen_create_room_topic_label">"Topic (optional)"</string> <string name="screen_create_room_topic_label">"Topic (optional)"</string>
<string name="screen_create_room_topic_placeholder">"Add description…"</string>
</resources> </resources>

View file

@ -40,6 +40,7 @@ class DefaultCreateRoomEntryPointTest {
override fun onRoomCreated(roomId: RoomId) = lambdaError() override fun onRoomCreated(roomId: RoomId) = lambdaError()
} }
val result = entryPoint.createNode( val result = entryPoint.createNode(
isSpace = false,
parentNode = parentNode, parentNode = parentNode,
buildContext = BuildContext.root(null), buildContext = BuildContext.root(null),
callback = callback, callback = callback,

View file

@ -51,15 +51,10 @@ import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService
import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.test import io.element.android.tests.testutils.test
import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkAll
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -76,17 +71,6 @@ class ConfigureRoomPresenterTest {
@get:Rule @get:Rule
val warmUpRule = WarmUpRule() val warmUpRule = WarmUpRule()
@Before
fun setup() {
mockkStatic(File::readBytes)
every { any<File>().readBytes() } returns byteArrayOf()
}
@After
fun tearDown() {
unmockkAll()
}
@Test @Test
fun `present - initial state`() = runTest { fun `present - initial state`() = runTest {
val presenter = createConfigureRoomPresenter() val presenter = createConfigureRoomPresenter()
@ -261,20 +245,25 @@ class ConfigureRoomPresenterTest {
val initialState = initialState() val initialState = initialState()
dataStore.setAvatarUri(Uri.parse(AN_URI_FROM_GALLERY)) dataStore.setAvatarUri(Uri.parse(AN_URI_FROM_GALLERY))
skipItems(1) skipItems(1)
mediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(mockk(), mockk(), mockk()))) val file = File.createTempFile("test", "jpg")
matrixClient.givenUploadMediaResult(Result.failure(AN_EXCEPTION)) try {
mediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(file, mockk(), mockk())))
matrixClient.givenUploadMediaResult(Result.failure(AN_EXCEPTION))
initialState.eventSink(ConfigureRoomEvents.CreateRoom) initialState.eventSink(ConfigureRoomEvents.CreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
val stateAfterCreateRoom = awaitItem() val stateAfterCreateRoom = awaitItem()
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java) assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
assertThat(analyticsService.capturedEvents.filterIsInstance<CreatedRoom>()).isEmpty() assertThat(analyticsService.capturedEvents.filterIsInstance<CreatedRoom>()).isEmpty()
matrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL)) matrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL))
stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom) stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java) assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java) assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
} finally {
file.delete()
}
} }
} }
@ -391,6 +380,7 @@ class ConfigureRoomPresenterTest {
) )
private fun createConfigureRoomPresenter( private fun createConfigureRoomPresenter(
isSpace: Boolean = false,
roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper(), roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper(),
dataStore: CreateRoomConfigStore = CreateRoomConfigStore(roomAliasHelper), dataStore: CreateRoomConfigStore = CreateRoomConfigStore(roomAliasHelper),
matrixClient: MatrixClient = createMatrixClient(), matrixClient: MatrixClient = createMatrixClient(),
@ -401,6 +391,7 @@ class ConfigureRoomPresenterTest {
isKnockFeatureEnabled: Boolean = true, isKnockFeatureEnabled: Boolean = true,
mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(), mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(),
) = ConfigureRoomPresenter( ) = ConfigureRoomPresenter(
isSpace = isSpace,
dataStore = dataStore, dataStore = dataStore,
matrixClient = matrixClient, matrixClient = matrixClient,
mediaPickerProvider = pickerProvider, mediaPickerProvider = pickerProvider,

View file

@ -14,6 +14,7 @@ import io.element.android.tests.testutils.lambda.lambdaError
class FakeCreateRoomEntryPoint : CreateRoomEntryPoint { class FakeCreateRoomEntryPoint : CreateRoomEntryPoint {
override fun createNode( override fun createNode(
isSpace: Boolean,
parentNode: Node, parentNode: Node,
buildContext: BuildContext, buildContext: BuildContext,
callback: CreateRoomEntryPoint.Callback, callback: CreateRoomEntryPoint.Callback,

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">"Potvrdite da želite deaktivirati svoj račun. Ova se radnja ne može poništiti."</string>
<string name="screen_deactivate_account_delete_all_messages">"Izbriši sve moje poruke"</string>
<string name="screen_deactivate_account_delete_all_messages_notice">"Upozorenje: budući korisnici mogu vidjeti nepotpune razgovore."</string>
<string name="screen_deactivate_account_description">"Deaktiviranje vašeg računa je %1$s, to će:"</string>
<string name="screen_deactivate_account_description_bold_part">"nepovratno"</string>
<string name="screen_deactivate_account_list_item_1">"%1$s vaš račun (ne možete se ponovno prijaviti i vaš ID se ne može ponovno upotrijebiti)."</string>
<string name="screen_deactivate_account_list_item_1_bold_part">"Trajno onemogući"</string>
<string name="screen_deactivate_account_list_item_2">"Ukloniti vas iz svih soba za razgovore."</string>
<string name="screen_deactivate_account_list_item_3">"Izbrisati podatke o vašem računu s našeg poslužitelja identiteta."</string>
<string name="screen_deactivate_account_list_item_4">"Vaše će poruke i dalje biti vidljive registriranim korisnicima, ali neće biti dostupne novim ili neregistriranim korisnicima ako ih odlučite izbrisati."</string>
<string name="screen_deactivate_account_title">"Deaktiviraj račun"</string>
</resources>

View file

@ -19,7 +19,7 @@ import dev.zacsweers.metro.AssistedInject
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.permissions.api.PermissionStateProvider import io.element.android.libraries.permissions.api.PermissionStateProvider
import io.element.android.libraries.permissions.api.PermissionsEvents import io.element.android.libraries.permissions.api.PermissionsEvent
import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.permissions.api.PermissionsPresenter
import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter
import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider
@ -58,7 +58,7 @@ class NotificationsOptInPresenter(
if (notificationsPermissionsState.permissionGranted) { if (notificationsPermissionsState.permissionGranted) {
callback.onNotificationsOptInFinished() callback.onNotificationsOptInFinished()
} else { } else {
notificationsPermissionsState.eventSink(PermissionsEvents.RequestPermissions) notificationsPermissionsState.eventSink(PermissionsEvent.RequestPermissions)
} }
} }
NotificationsOptInEvents.NotNowClicked -> { NotificationsOptInEvents.NotNowClicked -> {

View file

@ -25,6 +25,7 @@ import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.ftue.impl.R import io.element.android.features.ftue.impl.R
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.atomic.atoms.LoadingButtonAtom
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
@ -111,13 +112,7 @@ private fun ChooseSelfVerificationModeButtons(
AsyncData.Uninitialized, AsyncData.Uninitialized,
is AsyncData.Failure, is AsyncData.Failure,
is AsyncData.Loading -> { is AsyncData.Loading -> {
Button( LoadingButtonAtom()
modifier = Modifier.fillMaxWidth(),
enabled = false,
showProgress = true,
text = stringResource(CommonStrings.common_loading),
onClick = {},
)
} }
is AsyncData.Success -> { is AsyncData.Success -> {
if (state.buttonsState.data.canUseAnotherDevice) { if (state.buttonsState.data.canUseAnotherDevice) {

View file

@ -0,0 +1,16 @@
<?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">"Ne možete potvrditi?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Izradi novi ključ za oporavak"</string>
<string name="screen_identity_confirmation_subtitle">"Potvrdite ovaj uređaj kako biste postavili sigurnu razmjenu poruka."</string>
<string name="screen_identity_confirmation_title">"Potvrdite svoj identitet"</string>
<string name="screen_identity_confirmation_use_another_device">"Upotrijebite drugi uređaj"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Upotrijebi ključ za oporavak"</string>
<string name="screen_identity_confirmed_subtitle">"Sada možete sigurno čitati ili slati poruke, a svatko s kim razgovarate također može vjerovati ovom uređaju."</string>
<string name="screen_identity_confirmed_title">"Uređaj je potvrđen"</string>
<string name="screen_identity_use_another_device">"Upotrijebite drugi uređaj"</string>
<string name="screen_identity_waiting_on_other_device">"Čekanje na drugi uređaj…"</string>
<string name="screen_notification_optin_subtitle">"Postavke možete promijeniti poslije."</string>
<string name="screen_notification_optin_title">"Omogućite obavijesti i nikada ne propustite poruku"</string>
<string name="screen_session_verification_enter_recovery_key">"Unesi ključ za oporavak"</string>
</resources>

View file

@ -25,6 +25,7 @@ interface HomeEntryPoint : FeatureEntryPoint {
interface Callback : Plugin { interface Callback : Plugin {
fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?)
fun navigateToCreateRoom() fun navigateToCreateRoom()
fun navigateToCreateSpace()
fun navigateToSettings() fun navigateToSettings()
fun navigateToSetUpRecovery() fun navigateToSetUpRecovery()
fun navigateToEnterRecoveryKey() fun navigateToEnterRecoveryKey()

View file

@ -220,6 +220,7 @@ class HomeFlowNode(
onRoomClick = ::navigateToRoom, onRoomClick = ::navigateToRoom,
onSettingsClick = callback::navigateToSettings, onSettingsClick = callback::navigateToSettings,
onStartChatClick = callback::navigateToCreateRoom, onStartChatClick = callback::navigateToCreateRoom,
onCreateSpaceClick = callback::navigateToCreateSpace,
onSetUpRecoveryClick = callback::navigateToSetUpRecovery, onSetUpRecoveryClick = callback::navigateToSetUpRecovery,
onConfirmRecoveryKeyClick = callback::navigateToEnterRecoveryKey, onConfirmRecoveryKeyClick = callback::navigateToEnterRecoveryKey,
onRoomSettingsClick = callback::navigateToRoomSettings, onRoomSettingsClick = callback::navigateToRoomSettings,

View file

@ -28,7 +28,7 @@ enum class HomeNavigationBarItem(
isSelected: Boolean, isSelected: Boolean,
) = when (this) { ) = when (this) {
Chats -> if (isSelected) CompoundIcons.ChatSolid() else CompoundIcons.Chat() Chats -> if (isSelected) CompoundIcons.ChatSolid() else CompoundIcons.Chat()
Spaces -> if (isSelected) CompoundIcons.WorkspaceSolid() else CompoundIcons.Workspace() Spaces -> if (isSelected) CompoundIcons.SpaceSolid() else CompoundIcons.Space()
} }
companion object { companion object {

View file

@ -28,8 +28,6 @@ import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.indicator.api.IndicatorService import io.element.android.libraries.indicator.api.IndicatorService
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncService
@ -48,7 +46,6 @@ class HomePresenter(
private val homeSpacesPresenter: Presenter<HomeSpacesState>, private val homeSpacesPresenter: Presenter<HomeSpacesState>,
private val logoutPresenter: Presenter<DirectLogoutState>, private val logoutPresenter: Presenter<DirectLogoutState>,
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability, private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,
private val featureFlagService: FeatureFlagService,
private val sessionStore: SessionStore, private val sessionStore: SessionStore,
private val announcementService: AnnouncementService, private val announcementService: AnnouncementService,
) : Presenter<HomeState> { ) : Presenter<HomeState> {
@ -69,9 +66,6 @@ class HomePresenter(
val canReportBug by remember { rageshakeFeatureAvailability.isAvailable() }.collectAsState(false) val canReportBug by remember { rageshakeFeatureAvailability.isAvailable() }.collectAsState(false)
val roomListState = roomListPresenter.present() val roomListState = roomListPresenter.present()
val homeSpacesState = homeSpacesPresenter.present() val homeSpacesState = homeSpacesPresenter.present()
val isSpaceFeatureEnabled by remember {
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Space)
}.collectAsState(initial = false)
var currentHomeNavigationBarItemOrdinal by rememberSaveable { mutableIntStateOf(HomeNavigationBarItem.Chats.ordinal) } var currentHomeNavigationBarItemOrdinal by rememberSaveable { mutableIntStateOf(HomeNavigationBarItem.Chats.ordinal) }
val currentHomeNavigationBarItem by remember { val currentHomeNavigationBarItem by remember {
derivedStateOf { derivedStateOf {
@ -117,7 +111,6 @@ class HomePresenter(
snackbarMessage = snackbarMessage, snackbarMessage = snackbarMessage,
canReportBug = canReportBug, canReportBug = canReportBug,
directLogoutState = directLogoutState, directLogoutState = directLogoutState,
isSpaceFeatureEnabled = isSpaceFeatureEnabled,
eventSink = ::handleEvent, eventSink = ::handleEvent,
) )
} }

View file

@ -29,10 +29,9 @@ data class HomeState(
val snackbarMessage: SnackbarMessage?, val snackbarMessage: SnackbarMessage?,
val canReportBug: Boolean, val canReportBug: Boolean,
val directLogoutState: DirectLogoutState, val directLogoutState: DirectLogoutState,
val isSpaceFeatureEnabled: Boolean,
val eventSink: (HomeEvents) -> Unit, val eventSink: (HomeEvents) -> Unit,
) { ) {
val displayActions = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats val displayActions = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats
val displayRoomListFilters = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats && roomListState.displayFilters val displayRoomListFilters = currentHomeNavigationBarItem == HomeNavigationBarItem.Chats && roomListState.displayFilters
val showNavigationBar = isSpaceFeatureEnabled && homeSpacesState.spaceRooms.isNotEmpty() val showNavigationBar = homeSpacesState.spaceRooms.isNotEmpty()
} }

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