Merge branch 'develop' into feature/fga/csam_preferences_server

This commit is contained in:
ganfra 2025-06-30 21:42:06 +02:00
commit 9663e4ef37
623 changed files with 4661 additions and 2049 deletions

View file

@ -4,6 +4,7 @@
<locale android:name="bg"/> <locale android:name="bg"/>
<locale android:name="cs"/> <locale android:name="cs"/>
<locale android:name="cy"/> <locale android:name="cy"/>
<locale android:name="da"/>
<locale android:name="de"/> <locale android:name="de"/>
<locale android:name="el"/> <locale android:name="el"/>
<locale android:name="en"/> <locale android:name="en"/>

View file

@ -50,11 +50,11 @@ import io.element.android.features.createroom.api.CreateRoomEntryPoint
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.logout.api.LogoutEntryPoint import io.element.android.features.logout.api.LogoutEntryPoint
import io.element.android.features.preferences.api.PreferencesEntryPoint import io.element.android.features.preferences.api.PreferencesEntryPoint
import io.element.android.features.roomdirectory.api.RoomDescription import io.element.android.features.roomdirectory.api.RoomDescription
import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint
import io.element.android.features.roomlist.api.RoomListEntryPoint
import io.element.android.features.securebackup.api.SecureBackupEntryPoint import io.element.android.features.securebackup.api.SecureBackupEntryPoint
import io.element.android.features.share.api.ShareEntryPoint import io.element.android.features.share.api.ShareEntryPoint
import io.element.android.features.userprofile.api.UserProfileEntryPoint import io.element.android.features.userprofile.api.UserProfileEntryPoint
@ -91,6 +91,15 @@ import java.time.Duration
import java.time.Instant import java.time.Instant
import java.util.Optional import java.util.Optional
import java.util.UUID import java.util.UUID
import kotlin.collections.List
import kotlin.collections.any
import kotlin.collections.emptyList
import kotlin.collections.first
import kotlin.collections.forEach
import kotlin.collections.listOf
import kotlin.collections.mapNotNull
import kotlin.collections.plus
import kotlin.collections.setOf
import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
import kotlin.time.toKotlinDuration import kotlin.time.toKotlinDuration
@ -99,7 +108,7 @@ import kotlin.time.toKotlinDuration
class LoggedInFlowNode @AssistedInject constructor( class LoggedInFlowNode @AssistedInject constructor(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val roomListEntryPoint: RoomListEntryPoint, private val homeEntryPoint: HomeEntryPoint,
private val preferencesEntryPoint: PreferencesEntryPoint, private val preferencesEntryPoint: PreferencesEntryPoint,
private val createRoomEntryPoint: CreateRoomEntryPoint, private val createRoomEntryPoint: CreateRoomEntryPoint,
private val appNavigationStateService: AppNavigationStateService, private val appNavigationStateService: AppNavigationStateService,
@ -162,7 +171,7 @@ class LoggedInFlowNode @AssistedInject constructor(
// Otherwise, the RoomList UI may be incorrectly displayed on top // Otherwise, the RoomList UI may be incorrectly displayed on top
withTimeout(5.seconds) { withTimeout(5.seconds) {
backstack.elements.first { elements -> backstack.elements.first { elements ->
elements.any { it.key.navTarget == NavTarget.RoomList } elements.any { it.key.navTarget == NavTarget.Home }
} }
} }
@ -188,7 +197,7 @@ class LoggedInFlowNode @AssistedInject constructor(
when (ftueState) { when (ftueState) {
is FtueState.Unknown -> Unit // Nothing to do is FtueState.Unknown -> Unit // Nothing to do
is FtueState.Incomplete -> backstack.safeRoot(NavTarget.Ftue) is FtueState.Incomplete -> backstack.safeRoot(NavTarget.Ftue)
is FtueState.Complete -> backstack.safeRoot(NavTarget.RoomList) is FtueState.Complete -> backstack.safeRoot(NavTarget.Home)
} }
} }
.launchIn(lifecycleScope) .launchIn(lifecycleScope)
@ -215,7 +224,7 @@ class LoggedInFlowNode @AssistedInject constructor(
data object LoggedInPermanent : NavTarget data object LoggedInPermanent : NavTarget
@Parcelize @Parcelize
data object RoomList : NavTarget data object Home : NavTarget
@Parcelize @Parcelize
data class Room( data class Room(
@ -272,8 +281,8 @@ class LoggedInFlowNode @AssistedInject constructor(
} }
createNode<LoggedInNode>(buildContext, listOf(callback)) createNode<LoggedInNode>(buildContext, listOf(callback))
} }
NavTarget.RoomList -> { NavTarget.Home -> {
val callback = object : RoomListEntryPoint.Callback { val callback = object : HomeEntryPoint.Callback {
override fun onRoomClick(roomId: RoomId) { override fun onRoomClick(roomId: RoomId) {
backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias())) backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias()))
} }
@ -306,7 +315,7 @@ class LoggedInFlowNode @AssistedInject constructor(
backstack.push(NavTarget.LogoutForNativeSlidingSyncMigrationNeeded) backstack.push(NavTarget.LogoutForNativeSlidingSyncMigrationNeeded)
} }
} }
roomListEntryPoint homeEntryPoint
.nodeBuilder(this, buildContext) .nodeBuilder(this, buildContext)
.callback(callback) .callback(callback)
.build() .build()
@ -490,7 +499,7 @@ class LoggedInFlowNode @AssistedInject constructor(
clearBackstack: Boolean, clearBackstack: Boolean,
) { ) {
waitForNavTargetAttached { navTarget -> waitForNavTargetAttached { navTarget ->
navTarget is NavTarget.RoomList navTarget is NavTarget.Home
} }
attachChild<RoomFlowNode> { attachChild<RoomFlowNode> {
val roomNavTarget = NavTarget.Room( val roomNavTarget = NavTarget.Room(
@ -507,7 +516,7 @@ class LoggedInFlowNode @AssistedInject constructor(
suspend fun attachUser(userId: UserId) { suspend fun attachUser(userId: UserId) {
waitForNavTargetAttached { navTarget -> waitForNavTargetAttached { navTarget ->
navTarget is NavTarget.RoomList navTarget is NavTarget.Home
} }
attachChild<Node> { attachChild<Node> {
backstack.push( backstack.push(
@ -520,7 +529,7 @@ class LoggedInFlowNode @AssistedInject constructor(
internal suspend fun attachIncomingShare(intent: Intent) { internal suspend fun attachIncomingShare(intent: Intent) {
waitForNavTargetAttached { navTarget -> waitForNavTargetAttached { navTarget ->
navTarget is NavTarget.RoomList navTarget is NavTarget.Home
} }
attachChild<Node> { attachChild<Node> {
backstack.push( backstack.push(
@ -558,7 +567,7 @@ private class AttachRoomOperation(
return if (clearBackstack) { return if (clearBackstack) {
// Makes sure the room list target is alone in the backstack and stashed // Makes sure the room list target is alone in the backstack and stashed
elements.mapNotNull { element -> elements.mapNotNull { element ->
if (element.key.navTarget == LoggedInFlowNode.NavTarget.RoomList) { if (element.key.navTarget == LoggedInFlowNode.NavTarget.Home) {
element.transitionTo(STASHED, this) element.transitionTo(STASHED, this)
} else { } else {
null null

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">"Log ud og opgradér"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s understøtter ikke længere den gamle protokol. Log ud og log ind igen for at fortsætte med at bruge appen."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Din hjemmeserver understøtter ikke længere den gamle protokol. Log ud og log ind igen for at fortsætte med at bruge appen."</string>
</resources>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_settings_help_us_improve">"Del anonyme brugsdata for at hjælpe os med at identificere problemer."</string>
<string name="screen_analytics_settings_read_terms">"Du kan læse alle vores vilkår %1$s."</string>
<string name="screen_analytics_settings_read_terms_content_link">"her"</string>
<string name="screen_analytics_settings_share_data">"Del analysedata"</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">"Vi vil ikke registrere eller profilere nogen personlige data"</string>
<string name="screen_analytics_prompt_help_us_improve">"Del anonyme brugsdata for at hjælpe os med at identificere problemer."</string>
<string name="screen_analytics_prompt_read_terms">"Du kan læse alle vores vilkår %1$s."</string>
<string name="screen_analytics_prompt_read_terms_content_link">"her"</string>
<string name="screen_analytics_prompt_settings">"Du kan slå dette fra når som helst"</string>
<string name="screen_analytics_prompt_third_party_sharing">"Vi deler ikke dine data med tredjeparter"</string>
<string name="screen_analytics_prompt_title">"Hjælp med at forbedre %1$s"</string>
</resources>

View file

@ -7,16 +7,6 @@
package io.element.android.features.call.impl.pip package io.element.android.features.call.impl.pip
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
open class PictureInPictureStateProvider : PreviewParameterProvider<PictureInPictureState> {
override val values: Sequence<PictureInPictureState>
get() = sequenceOf(
aPictureInPictureState(supportPip = true),
aPictureInPictureState(supportPip = true, isInPictureInPicture = true),
)
}
fun aPictureInPictureState( fun aPictureInPictureState(
supportPip: Boolean = false, supportPip: Boolean = false,
isInPictureInPicture: Boolean = false, isInPictureInPicture: Boolean = false,

View file

@ -11,6 +11,7 @@ import android.annotation.SuppressLint
import android.util.Log import android.util.Log
import android.view.ViewGroup import android.view.ViewGroup
import android.webkit.ConsoleMessage import android.webkit.ConsoleMessage
import android.webkit.JavascriptInterface
import android.webkit.PermissionRequest import android.webkit.PermissionRequest
import android.webkit.WebChromeClient import android.webkit.WebChromeClient
import android.webkit.WebView import android.webkit.WebView
@ -19,7 +20,6 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -32,11 +32,9 @@ import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.call.impl.R import io.element.android.features.call.impl.R
import io.element.android.features.call.impl.pip.PictureInPictureEvents import io.element.android.features.call.impl.pip.PictureInPictureEvents
import io.element.android.features.call.impl.pip.PictureInPictureState import io.element.android.features.call.impl.pip.PictureInPictureState
import io.element.android.features.call.impl.pip.PictureInPictureStateProvider
import io.element.android.features.call.impl.pip.aPictureInPictureState import io.element.android.features.call.impl.pip.aPictureInPictureState
import io.element.android.features.call.impl.utils.InvalidAudioDeviceReason import io.element.android.features.call.impl.utils.InvalidAudioDeviceReason
import io.element.android.features.call.impl.utils.WebViewAudioManager import io.element.android.features.call.impl.utils.WebViewAudioManager
@ -44,13 +42,11 @@ import io.element.android.features.call.impl.utils.WebViewPipController
import io.element.android.features.call.impl.utils.WebViewWidgetMessageInterceptor import io.element.android.features.call.impl.utils.WebViewWidgetMessageInterceptor
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.components.ProgressDialog import io.element.android.libraries.designsystem.components.ProgressDialog
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
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.TopAppBar
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import timber.log.Timber import timber.log.Timber
@ -60,7 +56,6 @@ interface CallScreenNavigator {
fun close() fun close()
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
internal fun CallScreenView( internal fun CallScreenView(
state: CallScreenState, state: CallScreenState,
@ -78,19 +73,6 @@ internal fun CallScreenView(
Scaffold( Scaffold(
modifier = modifier, modifier = modifier,
topBar = {
if (!pipState.isInPictureInPicture) {
TopAppBar(
title = { Text(stringResource(R.string.element_call)) },
navigationIcon = {
BackButton(
imageVector = if (pipState.supportPip) CompoundIcons.ArrowLeft() else CompoundIcons.Close(),
onClick = ::handleBack,
)
}
)
}
}
) { padding -> ) { padding ->
BackHandler { BackHandler {
handleBack() handleBack()
@ -127,9 +109,11 @@ internal fun CallScreenView(
requestPermissions(androidPermissions.toTypedArray(), callback) requestPermissions(androidPermissions.toTypedArray(), callback)
}, },
onCreateWebView = { webView -> onCreateWebView = { webView ->
webView.addBackHandler(onBackPressed = ::handleBack)
val interceptor = WebViewWidgetMessageInterceptor( val interceptor = WebViewWidgetMessageInterceptor(
webView = webView, webView = webView,
onUrlLoaded = { url -> onUrlLoaded = { url ->
webView.evaluateJavascript("controls.onBackButtonPressed = () => { backHandler.onBackPressed() }", null)
if (webViewAudioManager?.isInCallMode?.get() == false) { if (webViewAudioManager?.isInCallMode?.get() == false) {
Timber.d("URL $url is loaded, starting in-call audio mode") Timber.d("URL $url is loaded, starting in-call audio mode")
webViewAudioManager?.onCallStarted() webViewAudioManager?.onCallStarted()
@ -282,6 +266,17 @@ private fun WebView.setup(
} }
} }
private fun WebView.addBackHandler(onBackPressed: () -> Unit) {
addJavascriptInterface(
object {
@Suppress("unused")
@JavascriptInterface
fun onBackPressed() = onBackPressed()
},
"backHandler"
)
}
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun CallScreenViewPreview( internal fun CallScreenViewPreview(
@ -294,18 +289,6 @@ internal fun CallScreenViewPreview(
) )
} }
@PreviewsDayNight
@Composable
internal fun CallScreenPipViewPreview(
@PreviewParameter(PictureInPictureStateProvider::class) state: PictureInPictureState,
) = ElementPreview {
CallScreenView(
state = aCallScreenState(),
pipState = state,
requestPermissions = { _, _ -> },
)
}
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun InvalidAudioDeviceDialogPreview() = ElementPreview { internal fun InvalidAudioDeviceDialogPreview() = ElementPreview {

View file

@ -3,5 +3,6 @@
<string name="call_foreground_service_channel_title_android">"Probíhající hovor"</string> <string name="call_foreground_service_channel_title_android">"Probíhající hovor"</string>
<string name="call_foreground_service_message_android">"Klepněte pro návrat k hovoru"</string> <string name="call_foreground_service_message_android">"Klepněte pro návrat k hovoru"</string>
<string name="call_foreground_service_title_android">"☎️ Probíhá hovor"</string> <string name="call_foreground_service_title_android">"☎️ Probíhá hovor"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"Element Call nepodporuje používání Bluetooth zvukových zařízení v této verzi systému Android. Vyberte jiné zvukové zařízení."</string>
<string name="screen_incoming_call_subtitle_android">"Příchozí Element Call"</string> <string name="screen_incoming_call_subtitle_android">"Příchozí Element Call"</string>
</resources> </resources>

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">"Igangværende opkald"</string>
<string name="call_foreground_service_message_android">"Tryk for at vende tilbage til opkaldet"</string>
<string name="call_foreground_service_title_android">"☎️ Opkald i gang"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"Element Call understøtter desværre ikke brug af Bluetooth-lydenheder i denne Android-version. Vælg venligst en anden lydenhed."</string>
<string name="screen_incoming_call_subtitle_android">"Indgående Element opkald"</string>
</resources>

View file

@ -3,5 +3,6 @@
<string name="call_foreground_service_channel_title_android">"Συνεχής κλήση"</string> <string name="call_foreground_service_channel_title_android">"Συνεχής κλήση"</string>
<string name="call_foreground_service_message_android">"Πάτα για να επιστρέψεις στην κλήση"</string> <string name="call_foreground_service_message_android">"Πάτα για να επιστρέψεις στην κλήση"</string>
<string name="call_foreground_service_title_android">"☎️ Κλήση σε εξέλιξη"</string> <string name="call_foreground_service_title_android">"☎️ Κλήση σε εξέλιξη"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"Το Element Call δεν υποστηρίζει τη χρήση συσκευών ήχου Bluetooth σε αυτήν την έκδοση Android. Επέλεξε μια διαφορετική συσκευή ήχου."</string>
<string name="screen_incoming_call_subtitle_android">"Εισερχόμενη κλήση Element"</string> <string name="screen_incoming_call_subtitle_android">"Εισερχόμενη κλήση Element"</string>
</resources> </resources>

View file

@ -3,5 +3,6 @@
<string name="call_foreground_service_channel_title_android">"Käimasolev kõne"</string> <string name="call_foreground_service_channel_title_android">"Käimasolev kõne"</string>
<string name="call_foreground_service_message_android">"Kõne juurde naasmiseks klõpsa"</string> <string name="call_foreground_service_message_android">"Kõne juurde naasmiseks klõpsa"</string>
<string name="call_foreground_service_title_android">"☎️ Kõne on pooleli"</string> <string name="call_foreground_service_title_android">"☎️ Kõne on pooleli"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"Element Call ei võimalda selles Androidi versioonis Bluetoothi heliseadmete kasutamist. Palun vali mõni muu heliseade."</string>
<string name="screen_incoming_call_subtitle_android">"Sissetulev Element Calli kõne"</string> <string name="screen_incoming_call_subtitle_android">"Sissetulev Element Calli kõne"</string>
</resources> </resources>

View file

@ -3,5 +3,6 @@
<string name="call_foreground_service_channel_title_android">"Folyamatban lévő hívás"</string> <string name="call_foreground_service_channel_title_android">"Folyamatban lévő hívás"</string>
<string name="call_foreground_service_message_android">"Koppintson a híváshoz való visszatéréshez"</string> <string name="call_foreground_service_message_android">"Koppintson a híváshoz való visszatéréshez"</string>
<string name="call_foreground_service_title_android">"☎️ Hívás folyamatban"</string> <string name="call_foreground_service_title_android">"☎️ Hívás folyamatban"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"Az Element Call nem támogatja a Bluetooth hangeszközök használatát ebben az Android-verzióban. Válasszon másik hangeszközt."</string>
<string name="screen_incoming_call_subtitle_android">"Bejövő Element hívás"</string> <string name="screen_incoming_call_subtitle_android">"Bejövő Element hívás"</string>
</resources> </resources>

View file

@ -3,5 +3,6 @@
<string name="call_foreground_service_channel_title_android">"Chamada em curso"</string> <string name="call_foreground_service_channel_title_android">"Chamada em curso"</string>
<string name="call_foreground_service_message_android">"Toca para voltar à chamada"</string> <string name="call_foreground_service_message_android">"Toca para voltar à chamada"</string>
<string name="call_foreground_service_title_android">"☎️ Chamada em curso"</string> <string name="call_foreground_service_title_android">"☎️ Chamada em curso"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"As chamadas do Element não permitem o uso de dispositivos de áudio Bluetooth nesta versão do Android. Por favor, seleciona outro dispositivo."</string>
<string name="screen_incoming_call_subtitle_android">"A receber chamada da Element"</string> <string name="screen_incoming_call_subtitle_android">"A receber chamada da Element"</string>
</resources> </resources>

View file

@ -3,5 +3,6 @@
<string name="call_foreground_service_channel_title_android">"Prebiehajúci hovor"</string> <string name="call_foreground_service_channel_title_android">"Prebiehajúci hovor"</string>
<string name="call_foreground_service_message_android">"Ťuknutím sa vrátite k hovoru"</string> <string name="call_foreground_service_message_android">"Ťuknutím sa vrátite k hovoru"</string>
<string name="call_foreground_service_title_android">"☎️ Prebieha hovor"</string> <string name="call_foreground_service_title_android">"☎️ Prebieha hovor"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"Element Call nepodporuje používanie zvukových zariadení Bluetooth v tejto verzii systému Android. Vyberte iné zvukové zariadenie."</string>
<string name="screen_incoming_call_subtitle_android">"Prichádzajúci hovor Element Call"</string> <string name="screen_incoming_call_subtitle_android">"Prichádzajúci hovor Element Call"</string>
</resources> </resources>

View file

@ -3,5 +3,6 @@
<string name="call_foreground_service_channel_title_android">"Поточний виклик"</string> <string name="call_foreground_service_channel_title_android">"Поточний виклик"</string>
<string name="call_foreground_service_message_android">"Торкніться, щоб повернутися до виклику"</string> <string name="call_foreground_service_message_android">"Торкніться, щоб повернутися до виклику"</string>
<string name="call_foreground_service_title_android">"☎️ Триває виклик"</string> <string name="call_foreground_service_title_android">"☎️ Триває виклик"</string>
<string name="call_invalid_audio_device_bluetooth_devices_disabled">"Element Call не підтримує використання аудіопристроїв Bluetooth у цій версії Android. Виберіть інший аудіопристрій."</string>
<string name="screen_incoming_call_subtitle_android">"Вхідний виклик Element"</string> <string name="screen_incoming_call_subtitle_android">"Вхідний виклик Element"</string>
</resources> </resources>

View file

@ -1,83 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.call.impl.ui
import androidx.activity.ComponentActivity
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.element.android.features.call.impl.pip.PictureInPictureEvents
import io.element.android.features.call.impl.pip.PictureInPictureState
import io.element.android.features.call.impl.pip.aPictureInPictureState
import io.element.android.tests.testutils.EventsRecorder
import io.element.android.tests.testutils.pressBack
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestRule
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class CallScreenViewTest {
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
@Test
fun `clicking on back when pip is not supported hangs up`() {
val eventsRecorder = EventsRecorder<CallScreenEvents>()
val pipEventsRecorder = EventsRecorder<PictureInPictureEvents>()
rule.setCallScreenView(
aCallScreenState(
eventSink = eventsRecorder
),
aPictureInPictureState(
supportPip = false,
eventSink = pipEventsRecorder,
),
)
rule.pressBack()
eventsRecorder.assertSize(2)
eventsRecorder.assertTrue(0) { it is CallScreenEvents.SetupMessageChannels }
eventsRecorder.assertTrue(1) { it == CallScreenEvents.Hangup }
pipEventsRecorder.assertSize(1)
pipEventsRecorder.assertTrue(0) { it is PictureInPictureEvents.SetPipController }
}
@Test
fun `clicking on back when pip is supported enables PiP`() {
val eventsRecorder = EventsRecorder<CallScreenEvents>()
val pipEventsRecorder = EventsRecorder<PictureInPictureEvents>()
rule.setCallScreenView(
aCallScreenState(
eventSink = eventsRecorder
),
aPictureInPictureState(
supportPip = true,
eventSink = pipEventsRecorder,
),
)
rule.pressBack()
eventsRecorder.assertSize(1)
eventsRecorder.assertTrue(0) { it is CallScreenEvents.SetupMessageChannels }
pipEventsRecorder.assertSize(2)
pipEventsRecorder.assertTrue(0) { it is PictureInPictureEvents.SetPipController }
pipEventsRecorder.assertTrue(1) { it == PictureInPictureEvents.EnterPictureInPicture }
}
}
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setCallScreenView(
state: CallScreenState,
pipState: PictureInPictureState,
requestPermissions: (Array<String>, RequestPermissionCallback) -> Unit = { _, _ -> },
) {
setContent {
CallScreenView(
state = state,
pipState = pipState,
requestPermissions = requestPermissions,
)
}
}

View file

@ -3,10 +3,21 @@
<string name="screen_create_room_action_create_room">"Нова стая"</string> <string name="screen_create_room_action_create_room">"Нова стая"</string>
<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_private_option_title">"Частна стая"</string>
<string name="screen_create_room_public_option_description">"Съобщенията не са шифровани и всеки може да ги прочете. Можете да активирате шифроването на по-късна дата."</string> <string name="screen_create_room_public_option_description">"Всеки може да намери тази стая.
Можете да промените това по всяко време в настройките на стаята."</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_address_section_footer">"За да бъде тази стая видима в директорията на общодостъпните стаи, ще ви е необходим адрес на стаята."</string>
<string name="screen_create_room_room_name_label">"Име на стаята"</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_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>
<string name="screen_start_chat_join_room_by_address_action">"Присъединяване към стая по адрес"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Не е валиден адрес"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Въведете…"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Стаята не е намерена"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"напр. #room-name:matrix.org"</string>
</resources> </resources>

View file

@ -0,0 +1,30 @@
<?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">"Nyt rum"</string>
<string name="screen_create_room_add_people_title">"Invitér folk"</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_title">"Privat rum"</string>
<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>
<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_title">"Spørg om at deltage"</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_title">"Rummets adresse"</string>
<string name="screen_create_room_room_name_label">"Navn på rum"</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_room_directory_search_title">"Register over rum"</string>
<string name="screen_start_chat_error_starting_chat">"Der opstod en fejl under forsøget på at starte en samtale"</string>
<string name="screen_start_chat_join_room_by_address_action">"Tilslut dig rummet med adressen"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Ikke en gyldig adresse"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Indtast…"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Matchende rum fundet"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Rum ikke fundet"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"f.eks. #rummets-navn:matrix.org"</string>
</resources>

View file

@ -1,30 +1,30 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_create_room_action_create_room">"Νέο δωμάτιο"</string> <string name="screen_create_room_action_create_room">"Νέα αίθουσα"</string>
<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_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_description">"Οποιοσδήποτε μπορεί να συμμετάσχει σε αυτή την αίθουσα"</string>
<string name="screen_create_room_room_access_section_anyone_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_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_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_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_title">"Δημιουργία αίθουσας"</string>
<string name="screen_create_room_topic_label">"Θέμα (προαιρετικό)"</string> <string name="screen_create_room_topic_label">"Θέμα (προαιρετικό)"</string>
<string name="screen_room_directory_search_title">"Κατάλογος δωματίων"</string> <string name="screen_room_directory_search_title">"Κατάλογος αιθουσών"</string>
<string name="screen_start_chat_error_starting_chat">"Παρουσιάστηκε σφάλμα κατά την προσπάθεια έναρξης μιας συνομιλίας"</string> <string name="screen_start_chat_error_starting_chat">"Παρουσιάστηκε σφάλμα κατά την προσπάθεια έναρξης μιας συνομιλίας"</string>
<string name="screen_start_chat_join_room_by_address_action">"Συμμετοχή σε δωμάτιο μέσω διεύθυνσης"</string> <string name="screen_start_chat_join_room_by_address_action">"Συμμετοχή σε αίθουσα μέσω διεύθυνσης"</string>
<string name="screen_start_chat_join_room_by_address_invalid_address">"Μη έγκυρη διεύθυνση"</string> <string name="screen_start_chat_join_room_by_address_invalid_address">"Μη έγκυρη διεύθυνση"</string>
<string name="screen_start_chat_join_room_by_address_placeholder">"Εισάγετε…"</string> <string name="screen_start_chat_join_room_by_address_placeholder">"Εισάγετε…"</string>
<string name="screen_start_chat_join_room_by_address_room_found">"Βρέθηκε το αντίστοιχο δωμάτιο"</string> <string name="screen_start_chat_join_room_by_address_room_found">"Βρέθηκε η αντίστοιχη αίθουσα"</string>
<string name="screen_start_chat_join_room_by_address_room_not_found">"Το δωμάτιο δε βρέθηκε"</string> <string name="screen_start_chat_join_room_by_address_room_not_found">"Η αίθουσα δεν βρέθηκε"</string>
<string name="screen_start_chat_join_room_by_address_supporting_text">"π.χ. #όνομα-δωματίου:matrix.org"</string> <string name="screen_start_chat_join_room_by_address_supporting_text">"π.χ. #όνομα-αίθουσας:matrix.org"</string>
</resources> </resources>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_deactivate_account_confirmation_dialog_content">"Моля, потвърдете, че искате да деактивирате акаунта си. Това действие не може да бъде отменено."</string>
<string name="screen_deactivate_account_title">"Деактивиране на акаунта"</string>
</resources>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_deactivate_account_confirmation_dialog_content">"Bekræft venligst, at du vil deaktivere din konto. Denne handling kan ikke fortrydes."</string>
<string name="screen_deactivate_account_delete_all_messages">"Slet alle mine beskeder"</string>
<string name="screen_deactivate_account_delete_all_messages_notice">"Advarsel: Fremtidige brugere kan muligvis se ufuldstændige samtaler."</string>
<string name="screen_deactivate_account_description">"Deaktivering af din konto er %1$s, det vil:"</string>
<string name="screen_deactivate_account_description_bold_part">"irreversibel"</string>
<string name="screen_deactivate_account_list_item_1">"%1$s din konto (du kan ikke logge ind igen, og dit ID kan ikke genbruges)."</string>
<string name="screen_deactivate_account_list_item_1_bold_part">"Deaktiver permanent"</string>
<string name="screen_deactivate_account_list_item_2">"Fjern dig fra alle samtalerum"</string>
<string name="screen_deactivate_account_list_item_3">"Slette dine kontooplysninger fra vores identitetsserver."</string>
<string name="screen_deactivate_account_list_item_4">"Dine beskeder vil stadig være synlige for registrerede brugere, men vil ikke være tilgængelige for nye eller uregistrerede brugere, hvis du vælger at slette dem."</string>
<string name="screen_deactivate_account_title">"Deaktiver konto"</string>
</resources>

View file

@ -7,7 +7,7 @@
<string name="screen_deactivate_account_description_bold_part">"μη αναστρέψιμο"</string> <string name="screen_deactivate_account_description_bold_part">"μη αναστρέψιμο"</string>
<string name="screen_deactivate_account_list_item_1">"%1$s τον λογαριασμό σου (δεν μπορείς να συνδεθείς ξανά και το αναγνωριστικό σου δεν μπορεί να επαναχρησιμοποιηθεί)."</string> <string name="screen_deactivate_account_list_item_1">"%1$s τον λογαριασμό σου (δεν μπορείς να συνδεθείς ξανά και το αναγνωριστικό σου δεν μπορεί να επαναχρησιμοποιηθεί)."</string>
<string name="screen_deactivate_account_list_item_1_bold_part">"Μόνιμη απενεργοποίηση"</string> <string name="screen_deactivate_account_list_item_1_bold_part">"Μόνιμη απενεργοποίηση"</string>
<string name="screen_deactivate_account_list_item_2">"Σε αφαιρέσει από όλα τα δωμάτια συνομιλίας."</string> <string name="screen_deactivate_account_list_item_2">"Αποχώρησή σας από όλες τις αίθουσες συνομιλίας."</string>
<string name="screen_deactivate_account_list_item_3">"Διαγράψει τα στοιχεία του λογαριασμού σου από τον διακομιστή ταυτότητάς μας."</string> <string name="screen_deactivate_account_list_item_3">"Διαγράψει τα στοιχεία του λογαριασμού σου από τον διακομιστή ταυτότητάς μας."</string>
<string name="screen_deactivate_account_list_item_4">"Τα μηνύματά σου θα εξακολουθούν να είναι ορατά στους εγγεγραμμένους χρήστες, αλλά δεν θα είναι διαθέσιμα σε νέους ή μη εγγεγραμμένους χρήστες εάν επιλέξεις να τα διαγράψεις."</string> <string name="screen_deactivate_account_list_item_4">"Τα μηνύματά σου θα εξακολουθούν να είναι ορατά στους εγγεγραμμένους χρήστες, αλλά δεν θα είναι διαθέσιμα σε νέους ή μη εγγεγραμμένους χρήστες εάν επιλέξεις να τα διαγράψεις."</string>
<string name="screen_deactivate_account_title">"Απενεργοποίηση λογαριασμού"</string> <string name="screen_deactivate_account_title">"Απενεργοποίηση λογαριασμού"</string>

View file

@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Не можете да потвърдите?"</string>
<string name="screen_identity_confirmation_subtitle">"Потвърдете това устройство, за да настроите защитени съобщения."</string>
<string name="screen_identity_confirmation_title">"Потвърдете самоличността си"</string>
<string name="screen_identity_confirmation_use_another_device">"Използване на друго устройство"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Използване на ключ за възстановяване"</string>
<string name="screen_identity_confirmed_title">"Устройството е потвърдено"</string>
<string name="screen_identity_use_another_device">"Използване на друго устройство"</string>
<string name="screen_notification_optin_subtitle">"Можете да промените настройките си по-късно."</string> <string name="screen_notification_optin_subtitle">"Можете да промените настройките си по-късно."</string>
<string name="screen_notification_optin_title">"Разрешете известията и никога не пропускайте съобщение"</string> <string name="screen_notification_optin_title">"Разрешете известията и никога не пропускайте съобщение"</string>
<string name="screen_session_verification_enter_recovery_key">"Въвеждане на ключ за възстановяване"</string> <string name="screen_session_verification_enter_recovery_key">"Въвеждане на ключ за възстановяване"</string>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_identity_confirmation_cannot_confirm">"Kan ikke bekræfte?"</string>
<string name="screen_identity_confirmation_create_new_recovery_key">"Opret en ny gendannelsesnøgle"</string>
<string name="screen_identity_confirmation_subtitle">"Verificér denne enhed for at konfigurere sikre meddelelser."</string>
<string name="screen_identity_confirmation_title">"Bekræft din identitet"</string>
<string name="screen_identity_confirmation_use_another_device">"Brug en anden enhed"</string>
<string name="screen_identity_confirmation_use_recovery_key">"Brug gendannelsesnøgle"</string>
<string name="screen_identity_confirmed_subtitle">"Nu kan du læse eller sende beskeder sikkert, og enhver du samtaler med kan også stole på denne enhed."</string>
<string name="screen_identity_confirmed_title">"Enhed verificeret"</string>
<string name="screen_identity_use_another_device">"Brug en anden enhed"</string>
<string name="screen_identity_waiting_on_other_device">"Venter på en anden enhed…"</string>
<string name="screen_notification_optin_subtitle">"Du kan ændre dine indstillinger senere."</string>
<string name="screen_notification_optin_title">"Tillad notifikationer, og gå aldrig glip af en besked"</string>
<string name="screen_session_verification_enter_recovery_key">"Indtast gendannelsesnøgle"</string>
<string name="screen_welcome_bullet_1">"Opkald, afstemninger, søgninger og mere vil blive tilføjet senere på året."</string>
<string name="screen_welcome_bullet_2">"Beskedhistorik for krypterede rum er ikke tilgængelig endnu."</string>
<string name="screen_welcome_bullet_3">"Vi vil meget gerne høre fra dig. Fortæl os din mening via indstillingssiden."</string>
<string name="screen_welcome_button">"Lad os komme i gang!"</string>
<string name="screen_welcome_subtitle">"Her er, hvad du har brug for at vide:"</string>
<string name="screen_welcome_title">"Velkommen til %1$s!"</string>
</resources>

View file

@ -14,7 +14,7 @@
<string name="screen_notification_optin_title">"Επέτρεψε τις ειδοποιήσεις και μην χάσεις ούτε ένα μήνυμα"</string> <string name="screen_notification_optin_title">"Επέτρεψε τις ειδοποιήσεις και μην χάσεις ούτε ένα μήνυμα"</string>
<string name="screen_session_verification_enter_recovery_key">"Εισαγωγή κλειδιού ανάκτησης"</string> <string name="screen_session_verification_enter_recovery_key">"Εισαγωγή κλειδιού ανάκτησης"</string>
<string name="screen_welcome_bullet_1">"Κλήσεις, δημοσκοπήσεις, αναζήτηση και άλλα, θα προστεθούν αργότερα φέτος."</string> <string name="screen_welcome_bullet_1">"Κλήσεις, δημοσκοπήσεις, αναζήτηση και άλλα, θα προστεθούν αργότερα φέτος."</string>
<string name="screen_welcome_bullet_2">"Το ιστορικό μηνυμάτων για κρυπτογραφημένα δωμάτια δεν είναι ακόμα διαθέσιμο."</string> <string name="screen_welcome_bullet_2">"Το ιστορικό μηνυμάτων για κρυπτογραφημένες αίθουσες δεν είναι ακόμη διαθέσιμο."</string>
<string name="screen_welcome_bullet_3">"Θα θέλαμε να ακούσουμε τη γνώμη σου, πες μας τη γνώμη σου μέσω της σελίδας ρυθμίσεων."</string> <string name="screen_welcome_bullet_3">"Θα θέλαμε να ακούσουμε τη γνώμη σου, πες μας τη γνώμη σου μέσω της σελίδας ρυθμίσεων."</string>
<string name="screen_welcome_button">"Πάμε!"</string> <string name="screen_welcome_button">"Πάμε!"</string>
<string name="screen_welcome_subtitle">"Να τί πρέπει να ξέρεις:"</string> <string name="screen_welcome_subtitle">"Να τί πρέπει να ξέρεις:"</string>

View file

@ -9,7 +9,7 @@ plugins {
} }
android { android {
namespace = "io.element.android.features.roomlist.api" namespace = "io.element.android.features.home.api"
} }
dependencies { dependencies {

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.api package io.element.android.features.home.api
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
@ -13,7 +13,7 @@ import com.bumble.appyx.core.plugin.Plugin
import io.element.android.libraries.architecture.FeatureEntryPoint import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
interface RoomListEntryPoint : FeatureEntryPoint { interface HomeEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder
interface NodeBuilder { interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder fun callback(callback: Callback): NodeBuilder

View file

@ -13,7 +13,7 @@ plugins {
} }
android { android {
namespace = "io.element.android.features.roomlist.impl" namespace = "io.element.android.features.home.impl"
testOptions { testOptions {
unitTests { unitTests {
@ -52,7 +52,7 @@ dependencies {
implementation(projects.services.analytics.api) implementation(projects.services.analytics.api)
implementation(libs.androidx.datastore.preferences) implementation(libs.androidx.datastore.preferences)
implementation(projects.features.reportroom.api) implementation(projects.features.reportroom.api)
api(projects.features.roomlist.api) api(projects.features.home.api)
testImplementation(libs.androidx.compose.ui.test.junit) testImplementation(libs.androidx.compose.ui.test.junit)
testReleaseImplementation(libs.androidx.compose.ui.test.manifest) testReleaseImplementation(libs.androidx.compose.ui.test.manifest)

View file

@ -5,30 +5,30 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import com.squareup.anvil.annotations.ContributesBinding import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.features.roomlist.api.RoomListEntryPoint import io.element.android.features.home.api.HomeEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
import javax.inject.Inject import javax.inject.Inject
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultRoomListEntryPoint @Inject constructor() : RoomListEntryPoint { class DefaultHomeEntryPoint @Inject constructor() : HomeEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomListEntryPoint.NodeBuilder { override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): HomeEntryPoint.NodeBuilder {
val plugins = ArrayList<Plugin>() val plugins = ArrayList<Plugin>()
return object : RoomListEntryPoint.NodeBuilder { return object : HomeEntryPoint.NodeBuilder {
override fun callback(callback: RoomListEntryPoint.Callback): RoomListEntryPoint.NodeBuilder { override fun callback(callback: HomeEntryPoint.Callback): HomeEntryPoint.NodeBuilder {
plugins += callback plugins += callback
return this return this
} }
override fun build(): Node { override fun build(): Node {
return parentNode.createNode<RoomListFlowNode>(buildContext, plugins) return parentNode.createNode<HomeFlowNode>(buildContext, plugins)
} }
} }
} }

View file

@ -0,0 +1,10 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.home.impl
sealed interface HomeEvents

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl
import android.app.Activity import android.app.Activity
import android.os.Parcelable import android.os.Parcelable
@ -24,14 +24,14 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.home.api.HomeEntryPoint
import io.element.android.features.home.impl.components.RoomListMenuAction
import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.invite.api.InviteData import io.element.android.features.invite.api.InviteData
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteView import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteView
import io.element.android.features.invite.api.declineandblock.DeclineInviteAndBlockEntryPoint import io.element.android.features.invite.api.declineandblock.DeclineInviteAndBlockEntryPoint
import io.element.android.features.logout.api.direct.DirectLogoutView import io.element.android.features.logout.api.direct.DirectLogoutView
import io.element.android.features.reportroom.api.ReportRoomEntryPoint import io.element.android.features.reportroom.api.ReportRoomEntryPoint
import io.element.android.features.roomlist.api.RoomListEntryPoint
import io.element.android.features.roomlist.impl.components.RoomListMenuAction
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
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.deeplink.usecase.InviteFriendsUseCase import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase
@ -41,17 +41,17 @@ import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ContributesNode(SessionScope::class) @ContributesNode(SessionScope::class)
class RoomListFlowNode @AssistedInject constructor( class HomeFlowNode @AssistedInject constructor(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: RoomListPresenter, private val presenter: HomePresenter,
private val inviteFriendsUseCase: InviteFriendsUseCase, private val inviteFriendsUseCase: InviteFriendsUseCase,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
private val acceptDeclineInviteView: AcceptDeclineInviteView, private val acceptDeclineInviteView: AcceptDeclineInviteView,
private val directLogoutView: DirectLogoutView, private val directLogoutView: DirectLogoutView,
private val reportRoomEntryPoint: ReportRoomEntryPoint, private val reportRoomEntryPoint: ReportRoomEntryPoint,
private val declineInviteAndBlockUserEntryPoint: DeclineInviteAndBlockEntryPoint, private val declineInviteAndBlockUserEntryPoint: DeclineInviteAndBlockEntryPoint,
) : BaseFlowNode<RoomListFlowNode.NavTarget>( ) : BaseFlowNode<HomeFlowNode.NavTarget>(
backstack = BackStack( backstack = BackStack(
initialElement = NavTarget.Root, initialElement = NavTarget.Root,
savedStateMap = buildContext.savedStateMap, savedStateMap = buildContext.savedStateMap,
@ -79,27 +79,27 @@ class RoomListFlowNode @AssistedInject constructor(
} }
private fun onRoomClick(roomId: RoomId) { private fun onRoomClick(roomId: RoomId) {
plugins<RoomListEntryPoint.Callback>().forEach { it.onRoomClick(roomId) } plugins<HomeEntryPoint.Callback>().forEach { it.onRoomClick(roomId) }
} }
private fun onOpenSettings() { private fun onOpenSettings() {
plugins<RoomListEntryPoint.Callback>().forEach { it.onSettingsClick() } plugins<HomeEntryPoint.Callback>().forEach { it.onSettingsClick() }
} }
private fun onCreateRoomClick() { private fun onCreateRoomClick() {
plugins<RoomListEntryPoint.Callback>().forEach { it.onCreateRoomClick() } plugins<HomeEntryPoint.Callback>().forEach { it.onCreateRoomClick() }
} }
private fun onSetUpRecoveryClick() { private fun onSetUpRecoveryClick() {
plugins<RoomListEntryPoint.Callback>().forEach { it.onSetUpRecoveryClick() } plugins<HomeEntryPoint.Callback>().forEach { it.onSetUpRecoveryClick() }
} }
private fun onSessionConfirmRecoveryKeyClick() { private fun onSessionConfirmRecoveryKeyClick() {
plugins<RoomListEntryPoint.Callback>().forEach { it.onSessionConfirmRecoveryKeyClick() } plugins<HomeEntryPoint.Callback>().forEach { it.onSessionConfirmRecoveryKeyClick() }
} }
private fun onRoomSettingsClick(roomId: RoomId) { private fun onRoomSettingsClick(roomId: RoomId) {
plugins<RoomListEntryPoint.Callback>().forEach { it.onRoomSettingsClick(roomId) } plugins<HomeEntryPoint.Callback>().forEach { it.onRoomSettingsClick(roomId) }
} }
private fun onReportRoomClick(roomId: RoomId) { private fun onReportRoomClick(roomId: RoomId) {
@ -116,7 +116,7 @@ class RoomListFlowNode @AssistedInject constructor(
inviteFriendsUseCase.execute(activity) inviteFriendsUseCase.execute(activity)
} }
RoomListMenuAction.ReportBug -> { RoomListMenuAction.ReportBug -> {
plugins<RoomListEntryPoint.Callback>().forEach { it.onReportBugClick() } plugins<HomeEntryPoint.Callback>().forEach { it.onReportBugClick() }
} }
} }
} }
@ -126,8 +126,8 @@ class RoomListFlowNode @AssistedInject constructor(
val state = presenter.present() val state = presenter.present()
val activity = requireNotNull(LocalActivity.current) val activity = requireNotNull(LocalActivity.current)
RoomListView( HomeView(
state = state, homeState = state,
onRoomClick = this::onRoomClick, onRoomClick = this::onRoomClick,
onSettingsClick = this::onOpenSettings, onSettingsClick = this::onOpenSettings,
onCreateRoomClick = this::onCreateRoomClick, onCreateRoomClick = this::onCreateRoomClick,
@ -140,7 +140,7 @@ class RoomListFlowNode @AssistedInject constructor(
modifier = modifier, modifier = modifier,
) { ) {
acceptDeclineInviteView.Render( acceptDeclineInviteView.Render(
state = state.acceptDeclineInviteState, state = state.roomListState.acceptDeclineInviteState,
onAcceptInviteSuccess = this::onRoomClick, onAcceptInviteSuccess = this::onRoomClick,
onDeclineInviteSuccess = { }, onDeclineInviteSuccess = { },
modifier = Modifier modifier = Modifier

View file

@ -0,0 +1,69 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.home.impl
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import io.element.android.features.home.impl.roomlist.RoomListState
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
import io.element.android.libraries.indicator.api.IndicatorService
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.sync.SyncService
import javax.inject.Inject
class HomePresenter @Inject constructor(
private val client: MatrixClient,
private val syncService: SyncService,
private val snackbarDispatcher: SnackbarDispatcher,
private val indicatorService: IndicatorService,
private val roomListPresenter: Presenter<RoomListState>,
private val logoutPresenter: Presenter<DirectLogoutState>,
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,
) : Presenter<HomeState> {
@Composable
override fun present(): HomeState {
val matrixUser = client.userProfile.collectAsState()
val isOnline by syncService.isOnline.collectAsState()
val canReportBug = remember { rageshakeFeatureAvailability.isAvailable() }
val roomListState = roomListPresenter.present()
LaunchedEffect(Unit) {
// Force a refresh of the profile
client.getUserProfile()
}
// Avatar indicator
val showAvatarIndicator by indicatorService.showRoomListTopBarIndicator()
val directLogoutState = logoutPresenter.present()
fun handleEvents(event: HomeEvents) {
// TODO
}
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
return HomeState(
matrixUser = matrixUser.value,
showAvatarIndicator = showAvatarIndicator,
hasNetworkConnection = isOnline,
roomListState = roomListState,
snackbarMessage = snackbarMessage,
canReportBug = canReportBug,
directLogoutState = directLogoutState,
eventSink = ::handleEvents,
)
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright 2023, 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.home.impl
import androidx.compose.runtime.Immutable
import io.element.android.features.home.impl.roomlist.RoomListState
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.user.MatrixUser
@Immutable
data class HomeState(
val matrixUser: MatrixUser,
val showAvatarIndicator: Boolean,
val hasNetworkConnection: Boolean,
val roomListState: RoomListState,
val snackbarMessage: SnackbarMessage?,
val canReportBug: Boolean,
val directLogoutState: DirectLogoutState,
val eventSink: (HomeEvents) -> Unit,
) {
val displayActions = true
}

View file

@ -0,0 +1,50 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.home.impl
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.home.impl.roomlist.RoomListState
import io.element.android.features.home.impl.roomlist.RoomListStateProvider
import io.element.android.features.home.impl.roomlist.aRoomListState
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.logout.api.direct.aDirectLogoutState
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.ui.strings.CommonStrings
open class HomeStateProvider : PreviewParameterProvider<HomeState> {
override val values: Sequence<HomeState>
get() = sequenceOf(
aHomeState(),
aHomeState(hasNetworkConnection = false),
aHomeState(snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete)),
) + RoomListStateProvider().values.map {
aHomeState(roomListState = it)
}
}
internal fun aHomeState(
matrixUser: MatrixUser = MatrixUser(userId = UserId("@id:domain"), displayName = "User#1"),
showAvatarIndicator: Boolean = false,
hasNetworkConnection: Boolean = true,
snackbarMessage: SnackbarMessage? = null,
roomListState: RoomListState = aRoomListState(),
canReportBug: Boolean = true,
directLogoutState: DirectLogoutState = aDirectLogoutState(),
eventSink: (HomeEvents) -> Unit = {}
) = HomeState(
matrixUser = matrixUser,
showAvatarIndicator = showAvatarIndicator,
hasNetworkConnection = hasNetworkConnection,
snackbarMessage = snackbarMessage,
canReportBug = canReportBug,
directLogoutState = directLogoutState,
roomListState = roomListState,
eventSink = eventSink,
)

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -25,13 +25,17 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.compound.theme.ElementTheme 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.home.impl.components.RoomListContentView
import io.element.android.features.home.impl.components.RoomListMenuAction
import io.element.android.features.home.impl.components.RoomListTopBar
import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.home.impl.roomlist.RoomListContextMenu
import io.element.android.features.home.impl.roomlist.RoomListDeclineInviteMenu
import io.element.android.features.home.impl.roomlist.RoomListEvents
import io.element.android.features.home.impl.roomlist.RoomListState
import io.element.android.features.home.impl.search.RoomListSearchView
import io.element.android.features.leaveroom.api.LeaveRoomView import io.element.android.features.leaveroom.api.LeaveRoomView
import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer
import io.element.android.features.roomlist.impl.components.RoomListContentView
import io.element.android.features.roomlist.impl.components.RoomListMenuAction
import io.element.android.features.roomlist.impl.components.RoomListTopBar
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.search.RoomListSearchView
import io.element.android.libraries.androidutils.throttler.FirstThrottler import io.element.android.libraries.androidutils.throttler.FirstThrottler
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@ -43,8 +47,8 @@ import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbar
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
@Composable @Composable
fun RoomListView( fun HomeView(
state: RoomListState, homeState: HomeState,
onRoomClick: (RoomId) -> Unit, onRoomClick: (RoomId) -> Unit,
onSettingsClick: () -> Unit, onSettingsClick: () -> Unit,
onSetUpRecoveryClick: () -> Unit, onSetUpRecoveryClick: () -> Unit,
@ -57,12 +61,13 @@ fun RoomListView(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
acceptDeclineInviteView: @Composable () -> Unit, acceptDeclineInviteView: @Composable () -> Unit,
) { ) {
val state: RoomListState = homeState.roomListState
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
val firstThrottler = remember { FirstThrottler(300, coroutineScope) } val firstThrottler = remember { FirstThrottler(300, coroutineScope) }
ConnectivityIndicatorContainer( ConnectivityIndicatorContainer(
modifier = modifier, modifier = modifier,
isOnline = state.hasNetworkConnection, isOnline = homeState.hasNetworkConnection,
) { topPadding -> ) { topPadding ->
Box { Box {
if (state.contextMenu is RoomListState.ContextMenu.Shown) { if (state.contextMenu is RoomListState.ContextMenu.Shown) {
@ -85,8 +90,8 @@ fun RoomListView(
LeaveRoomView(state = state.leaveRoomState) LeaveRoomView(state = state.leaveRoomState)
RoomListScaffold( HomeScaffold(
state = state, state = homeState,
onSetUpRecoveryClick = onSetUpRecoveryClick, onSetUpRecoveryClick = onSetUpRecoveryClick,
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick, onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
onRoomClick = { if (firstThrottler.canHandle()) onRoomClick(it) }, onRoomClick = { if (firstThrottler.canHandle()) onRoomClick(it) },
@ -114,8 +119,8 @@ fun RoomListView(
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun RoomListScaffold( private fun HomeScaffold(
state: RoomListState, state: HomeState,
onSetUpRecoveryClick: () -> Unit, onSetUpRecoveryClick: () -> Unit,
onConfirmRecoveryKeyClick: () -> Unit, onConfirmRecoveryKeyClick: () -> Unit,
onRoomClick: (RoomId) -> Unit, onRoomClick: (RoomId) -> Unit,
@ -131,6 +136,7 @@ private fun RoomListScaffold(
val appBarState = rememberTopAppBarState() val appBarState = rememberTopAppBarState()
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(appBarState) val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(appBarState)
val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage) val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage)
val roomListState: RoomListState = state.roomListState
Scaffold( Scaffold(
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
@ -138,23 +144,23 @@ private fun RoomListScaffold(
RoomListTopBar( RoomListTopBar(
matrixUser = state.matrixUser, matrixUser = state.matrixUser,
showAvatarIndicator = state.showAvatarIndicator, showAvatarIndicator = state.showAvatarIndicator,
areSearchResultsDisplayed = state.searchState.isSearchActive, areSearchResultsDisplayed = roomListState.searchState.isSearchActive,
onToggleSearch = { state.eventSink(RoomListEvents.ToggleSearchResults) }, onToggleSearch = { roomListState.eventSink(RoomListEvents.ToggleSearchResults) },
onMenuActionClick = onMenuActionClick, onMenuActionClick = onMenuActionClick,
onOpenSettings = onOpenSettings, onOpenSettings = onOpenSettings,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
displayMenuItems = state.displayActions, displayMenuItems = state.displayActions,
displayFilters = state.displayFilters, displayFilters = roomListState.displayFilters,
filtersState = state.filtersState, filtersState = roomListState.filtersState,
canReportBug = state.canReportBug, canReportBug = state.canReportBug,
) )
}, },
content = { padding -> content = { padding ->
RoomListContentView( RoomListContentView(
contentState = state.contentState, contentState = roomListState.contentState,
filtersState = state.filtersState, filtersState = roomListState.filtersState,
hideInvitesAvatars = state.hideInvitesAvatars, hideInvitesAvatars = roomListState.hideInvitesAvatars,
eventSink = state.eventSink, eventSink = roomListState.eventSink,
onSetUpRecoveryClick = onSetUpRecoveryClick, onSetUpRecoveryClick = onSetUpRecoveryClick,
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick, onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
onRoomClick = ::onRoomClick, onRoomClick = ::onRoomClick,
@ -186,9 +192,9 @@ internal fun RoomListRoomSummary.contentType() = displayType.ordinal
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun RoomListViewPreview(@PreviewParameter(RoomListStateProvider::class) state: RoomListState) = ElementPreview { internal fun HomeViewPreview(@PreviewParameter(HomeStateProvider::class) state: HomeState) = ElementPreview {
RoomListView( HomeView(
state = state, homeState = state,
onRoomClick = {}, onRoomClick = {},
onSettingsClick = {}, onSettingsClick = {},
onSetUpRecoveryClick = {}, onSetUpRecoveryClick = {},

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier

View file

@ -5,12 +5,12 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import io.element.android.features.roomlist.impl.R import io.element.android.features.home.impl.R
import io.element.android.libraries.designsystem.components.Announcement import io.element.android.libraries.designsystem.components.Announcement
import io.element.android.libraries.designsystem.components.AnnouncementType import io.element.android.libraries.designsystem.components.AnnouncementType
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview

View file

@ -5,12 +5,12 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import io.element.android.features.roomlist.impl.R import io.element.android.features.home.impl.R
import io.element.android.libraries.designsystem.components.Announcement import io.element.android.libraries.designsystem.components.Announcement
import io.element.android.libraries.designsystem.components.AnnouncementType import io.element.android.libraries.designsystem.components.AnnouncementType
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview

View file

@ -5,12 +5,12 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import io.element.android.features.roomlist.impl.R import io.element.android.features.home.impl.R
import io.element.android.libraries.designsystem.components.Announcement import io.element.android.libraries.designsystem.components.Announcement
import io.element.android.libraries.designsystem.components.AnnouncementType import io.element.android.libraries.designsystem.components.AnnouncementType
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -34,19 +34,19 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme 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.roomlist.impl.R import io.element.android.features.home.impl.R
import io.element.android.features.roomlist.impl.RoomListContentState import io.element.android.features.home.impl.contentType
import io.element.android.features.roomlist.impl.RoomListContentStateProvider import io.element.android.features.home.impl.filters.RoomListFilter
import io.element.android.features.roomlist.impl.RoomListEvents import io.element.android.features.home.impl.filters.RoomListFiltersEmptyStateResources
import io.element.android.features.roomlist.impl.SecurityBannerState import io.element.android.features.home.impl.filters.RoomListFiltersState
import io.element.android.features.roomlist.impl.contentType import io.element.android.features.home.impl.filters.aRoomListFiltersState
import io.element.android.features.roomlist.impl.filters.RoomListFilter import io.element.android.features.home.impl.filters.selection.FilterSelectionState
import io.element.android.features.roomlist.impl.filters.RoomListFiltersEmptyStateResources import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.filters.RoomListFiltersState import io.element.android.features.home.impl.model.RoomSummaryDisplayType
import io.element.android.features.roomlist.impl.filters.aRoomListFiltersState import io.element.android.features.home.impl.roomlist.RoomListContentState
import io.element.android.features.roomlist.impl.filters.selection.FilterSelectionState import io.element.android.features.home.impl.roomlist.RoomListContentStateProvider
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.roomlist.RoomListEvents
import io.element.android.features.roomlist.impl.model.RoomSummaryDisplayType import io.element.android.features.home.impl.roomlist.SecurityBannerState
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.Button
@ -311,7 +311,12 @@ internal fun RoomListContentViewPreview(@PreviewParameter(RoomListContentStatePr
RoomListContentView( RoomListContentView(
contentState = state, contentState = state,
filtersState = aRoomListFiltersState( filtersState = aRoomListFiltersState(
filterSelectionStates = RoomListFilter.entries.map { FilterSelectionState(it, isSelected = true) } filterSelectionStates = RoomListFilter.entries.map {
FilterSelectionState(
filter = it,
isSelected = true
)
}
), ),
hideInvitesAvatars = false, hideInvitesAvatars = false,
eventSink = {}, eventSink = {},

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
enum class RoomListMenuAction { enum class RoomListMenuAction {
InviteFriends, InviteFriends,

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -40,10 +40,10 @@ import androidx.compose.ui.unit.dp
import io.element.android.appconfig.RoomListConfig import io.element.android.appconfig.RoomListConfig
import io.element.android.compound.theme.ElementTheme 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.roomlist.impl.R import io.element.android.features.home.impl.R
import io.element.android.features.roomlist.impl.filters.RoomListFiltersState import io.element.android.features.home.impl.filters.RoomListFiltersState
import io.element.android.features.roomlist.impl.filters.RoomListFiltersView import io.element.android.features.home.impl.filters.RoomListFiltersView
import io.element.android.features.roomlist.impl.filters.aRoomListFiltersState import io.element.android.features.home.impl.filters.aRoomListFiltersState
import io.element.android.libraries.designsystem.atomic.atoms.RedIndicatorAtom import io.element.android.libraries.designsystem.atomic.atoms.RedIndicatorAtom
import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
@ -37,11 +37,11 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme 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.roomlist.impl.R import io.element.android.features.home.impl.R
import io.element.android.features.roomlist.impl.RoomListEvents import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummaryProvider
import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryProvider import io.element.android.features.home.impl.model.RoomSummaryDisplayType
import io.element.android.features.roomlist.impl.model.RoomSummaryDisplayType import io.element.android.features.home.impl.roomlist.RoomListEvents
import io.element.android.libraries.core.extensions.orEmpty import io.element.android.libraries.core.extensions.orEmpty
import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom
import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.Avatar

View file

@ -5,12 +5,12 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.components package io.element.android.features.home.impl.components
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import io.element.android.features.roomlist.impl.R import io.element.android.features.home.impl.R
import io.element.android.libraries.designsystem.components.Announcement import io.element.android.libraries.designsystem.components.Announcement
import io.element.android.libraries.designsystem.components.AnnouncementType import io.element.android.libraries.designsystem.components.AnnouncementType
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview

View file

@ -5,9 +5,9 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.datasource package io.element.android.features.home.impl.datasource
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.libraries.androidutils.diff.DiffCacheUpdater import io.element.android.libraries.androidutils.diff.DiffCacheUpdater
import io.element.android.libraries.androidutils.diff.MutableListDiffCache import io.element.android.libraries.androidutils.diff.MutableListDiffCache
import io.element.android.libraries.androidutils.system.DateTimeObserver import io.element.android.libraries.androidutils.system.DateTimeObserver

View file

@ -5,10 +5,10 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.datasource package io.element.android.features.home.impl.datasource
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.model.RoomSummaryDisplayType import io.element.android.features.home.impl.model.RoomSummaryDisplayType
import io.element.android.libraries.core.extensions.orEmpty import io.element.android.libraries.core.extensions.orEmpty
import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.api.DateFormatter
import io.element.android.libraries.dateformatter.api.DateFormatterMode import io.element.android.libraries.dateformatter.api.DateFormatterMode

View file

@ -5,21 +5,26 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.di package io.element.android.features.home.impl.di
import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module
import io.element.android.features.roomlist.impl.filters.RoomListFiltersPresenter import io.element.android.features.home.impl.filters.RoomListFiltersPresenter
import io.element.android.features.roomlist.impl.filters.RoomListFiltersState import io.element.android.features.home.impl.filters.RoomListFiltersState
import io.element.android.features.roomlist.impl.search.RoomListSearchPresenter import io.element.android.features.home.impl.roomlist.RoomListPresenter
import io.element.android.features.roomlist.impl.search.RoomListSearchState import io.element.android.features.home.impl.roomlist.RoomListState
import io.element.android.features.home.impl.search.RoomListSearchPresenter
import io.element.android.features.home.impl.search.RoomListSearchState
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ContributesTo(SessionScope::class) @ContributesTo(SessionScope::class)
@Module @Module
interface RoomListModule { interface RoomListModule {
@Binds
fun bindRoomListPresenter(presenter: RoomListPresenter): Presenter<RoomListState>
@Binds @Binds
fun bindSearchPresenter(presenter: RoomListSearchPresenter): Presenter<RoomListSearchState> fun bindSearchPresenter(presenter: RoomListSearchPresenter): Presenter<RoomListSearchState>

View file

@ -5,9 +5,9 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters package io.element.android.features.home.impl.filters
import io.element.android.features.roomlist.impl.R import io.element.android.features.home.impl.R
/** /**
* Enum class representing the different filters that can be applied to the room list. * Enum class representing the different filters that can be applied to the room list.

View file

@ -5,10 +5,10 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters package io.element.android.features.home.impl.filters
import androidx.annotation.StringRes import androidx.annotation.StringRes
import io.element.android.features.roomlist.impl.R import io.element.android.features.home.impl.R
/** /**
* Holds the resources for the empty state when filters are applied to the room list. * Holds the resources for the empty state when filters are applied to the room list.

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters package io.element.android.features.home.impl.filters
sealed interface RoomListFiltersEvents { sealed interface RoomListFiltersEvents {
data class ToggleFilter(val filter: RoomListFilter) : RoomListFiltersEvents data class ToggleFilter(val filter: RoomListFilter) : RoomListFiltersEvents

View file

@ -5,12 +5,12 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters package io.element.android.features.home.impl.filters
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState import androidx.compose.runtime.produceState
import io.element.android.features.roomlist.impl.filters.selection.FilterSelectionStrategy import io.element.android.features.home.impl.filters.selection.FilterSelectionStrategy
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList

View file

@ -5,9 +5,9 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters package io.element.android.features.home.impl.filters
import io.element.android.features.roomlist.impl.filters.selection.FilterSelectionState import io.element.android.features.home.impl.filters.selection.FilterSelectionState
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList

View file

@ -5,10 +5,10 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters package io.element.android.features.home.impl.filters
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.roomlist.impl.filters.selection.FilterSelectionState import io.element.android.features.home.impl.filters.selection.FilterSelectionState
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
class RoomListFiltersStateProvider : PreviewParameterProvider<RoomListFiltersState> { class RoomListFiltersStateProvider : PreviewParameterProvider<RoomListFiltersState> {

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters package io.element.android.features.home.impl.filters
import androidx.compose.animation.animateColorAsState import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.Spring import androidx.compose.animation.core.Spring
@ -40,6 +40,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex import androidx.compose.ui.zIndex
import io.element.android.compound.theme.ElementTheme 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.home.impl.R
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Icon
@ -147,7 +148,7 @@ private fun RoomListClearFiltersButton(
modifier = Modifier.align(Alignment.Center), modifier = Modifier.align(Alignment.Center),
imageVector = CompoundIcons.Close(), imageVector = CompoundIcons.Close(),
tint = ElementTheme.colors.iconOnSolidPrimary, tint = ElementTheme.colors.iconOnSolidPrimary,
contentDescription = stringResource(id = io.element.android.libraries.ui.strings.R.string.action_clear), contentDescription = stringResource(id = R.string.screen_roomlist_clear_filters),
) )
} }
} }

View file

@ -5,10 +5,10 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters.selection package io.element.android.features.home.impl.filters.selection
import com.squareup.anvil.annotations.ContributesBinding import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.features.roomlist.impl.filters.RoomListFilter import io.element.android.features.home.impl.filters.RoomListFilter
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject import javax.inject.Inject

View file

@ -5,9 +5,9 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters.selection package io.element.android.features.home.impl.filters.selection
import io.element.android.features.roomlist.impl.filters.RoomListFilter import io.element.android.features.home.impl.filters.RoomListFilter
data class FilterSelectionState( data class FilterSelectionState(
val filter: RoomListFilter, val filter: RoomListFilter,

View file

@ -5,9 +5,9 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.filters.selection package io.element.android.features.home.impl.filters.selection
import io.element.android.features.roomlist.impl.filters.RoomListFilter import io.element.android.features.home.impl.filters.RoomListFilter
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
interface FilterSelectionStrategy { interface FilterSelectionStrategy {

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.model package io.element.android.features.home.impl.model
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import io.element.android.features.invite.api.InviteData import io.element.android.features.invite.api.InviteData

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.model package io.element.android.features.home.impl.model
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarData

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.model package io.element.android.features.home.impl.model
/** /**
* Represents the type of display for a room list item. * Represents the type of display for a room list item.

View file

@ -5,10 +5,10 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl.roomlist
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState
import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl.roomlist
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -19,6 +19,7 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.compound.theme.ElementTheme 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.home.impl.R
import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl.roomlist
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@ -20,7 +20,8 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.R
import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.Button

View file

@ -5,9 +5,9 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl.roomlist
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
sealed interface RoomListEvents { sealed interface RoomListEvents {

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl.roomlist
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@ -23,18 +23,16 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow import androidx.compose.runtime.snapshotFlow
import im.vector.app.features.analytics.plan.Interaction import im.vector.app.features.analytics.plan.Interaction
import io.element.android.features.home.impl.datasource.RoomListDataSource
import io.element.android.features.home.impl.filters.RoomListFiltersState
import io.element.android.features.home.impl.search.RoomListSearchEvents
import io.element.android.features.home.impl.search.RoomListSearchState
import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.api.SeenInvitesStore
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.AcceptInvite import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.AcceptInvite
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.DeclineInvite import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.DeclineInvite
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.leaveroom.api.LeaveRoomEvent.ShowConfirmation import io.element.android.features.leaveroom.api.LeaveRoomEvent.ShowConfirmation
import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.leaveroom.api.LeaveRoomState
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
import io.element.android.features.roomlist.impl.datasource.RoomListDataSource
import io.element.android.features.roomlist.impl.filters.RoomListFiltersState
import io.element.android.features.roomlist.impl.search.RoomListSearchEvents
import io.element.android.features.roomlist.impl.search.RoomListSearchState
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.coroutine.mapState import io.element.android.libraries.core.coroutine.mapState
@ -43,13 +41,11 @@ import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarM
import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState
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.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.encryption.RecoveryState
import io.element.android.libraries.matrix.api.roomlist.RoomList import io.element.android.libraries.matrix.api.roomlist.RoomList
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.ReceiptType
import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
@ -78,12 +74,9 @@ private const val SUBSCRIBE_TO_VISIBLE_ROOMS_DEBOUNCE_IN_MILLIS = 300L
class RoomListPresenter @Inject constructor( class RoomListPresenter @Inject constructor(
private val client: MatrixClient, private val client: MatrixClient,
private val syncService: SyncService,
private val snackbarDispatcher: SnackbarDispatcher,
private val leaveRoomPresenter: Presenter<LeaveRoomState>, private val leaveRoomPresenter: Presenter<LeaveRoomState>,
private val roomListDataSource: RoomListDataSource, private val roomListDataSource: RoomListDataSource,
private val featureFlagService: FeatureFlagService, private val featureFlagService: FeatureFlagService,
private val indicatorService: IndicatorService,
private val filtersPresenter: Presenter<RoomListFiltersState>, private val filtersPresenter: Presenter<RoomListFiltersState>,
private val searchPresenter: Presenter<RoomListSearchState>, private val searchPresenter: Presenter<RoomListSearchState>,
private val sessionPreferencesStore: SessionPreferencesStore, private val sessionPreferencesStore: SessionPreferencesStore,
@ -92,9 +85,7 @@ class RoomListPresenter @Inject constructor(
private val fullScreenIntentPermissionsPresenter: Presenter<FullScreenIntentPermissionsState>, private val fullScreenIntentPermissionsPresenter: Presenter<FullScreenIntentPermissionsState>,
private val batteryOptimizationPresenter: Presenter<BatteryOptimizationState>, private val batteryOptimizationPresenter: Presenter<BatteryOptimizationState>,
private val notificationCleaner: NotificationCleaner, private val notificationCleaner: NotificationCleaner,
private val logoutPresenter: Presenter<DirectLogoutState>,
private val appPreferencesStore: AppPreferencesStore, private val appPreferencesStore: AppPreferencesStore,
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,
private val seenInvitesStore: SeenInvitesStore, private val seenInvitesStore: SeenInvitesStore,
) : Presenter<RoomListState> { ) : Presenter<RoomListState> {
private val encryptionService: EncryptionService = client.encryptionService() private val encryptionService: EncryptionService = client.encryptionService()
@ -103,23 +94,17 @@ class RoomListPresenter @Inject constructor(
override fun present(): RoomListState { override fun present(): RoomListState {
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
val leaveRoomState = leaveRoomPresenter.present() val leaveRoomState = leaveRoomPresenter.present()
val matrixUser = client.userProfile.collectAsState()
val isOnline by syncService.isOnline.collectAsState()
val filtersState = filtersPresenter.present() val filtersState = filtersPresenter.present()
val searchState = searchPresenter.present() val searchState = searchPresenter.present()
val acceptDeclineInviteState = acceptDeclineInvitePresenter.present() val acceptDeclineInviteState = acceptDeclineInvitePresenter.present()
val canReportBug = remember { rageshakeFeatureAvailability.isAvailable() }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
roomListDataSource.launchIn(this) roomListDataSource.launchIn(this)
// Force a refresh of the profile
client.getUserProfile()
} }
var securityBannerDismissed by rememberSaveable { mutableStateOf(false) } var securityBannerDismissed by rememberSaveable { mutableStateOf(false) }
// Avatar indicator // Avatar indicator
val showAvatarIndicator by indicatorService.showRoomListTopBarIndicator()
val hideInvitesAvatar by remember { val hideInvitesAvatar by remember {
client client
.mediaPreviewService() .mediaPreviewService()
@ -130,8 +115,6 @@ class RoomListPresenter @Inject constructor(
val contextMenu = remember { mutableStateOf<RoomListState.ContextMenu>(RoomListState.ContextMenu.Hidden) } val contextMenu = remember { mutableStateOf<RoomListState.ContextMenu>(RoomListState.ContextMenu.Hidden) }
val declineInviteMenu = remember { mutableStateOf<RoomListState.DeclineInviteMenu>(RoomListState.DeclineInviteMenu.Hidden) } val declineInviteMenu = remember { mutableStateOf<RoomListState.DeclineInviteMenu>(RoomListState.DeclineInviteMenu.Hidden) }
val directLogoutState = logoutPresenter.present()
fun handleEvents(event: RoomListEvents) { fun handleEvents(event: RoomListEvents) {
when (event) { when (event) {
is RoomListEvents.UpdateVisibleRange -> coroutineScope.launch { is RoomListEvents.UpdateVisibleRange -> coroutineScope.launch {
@ -166,26 +149,18 @@ class RoomListPresenter @Inject constructor(
} }
} }
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
val contentState = roomListContentState(securityBannerDismissed) val contentState = roomListContentState(securityBannerDismissed)
val canReportRoom by produceState(false) { value = client.canReportRoom() } val canReportRoom by produceState(false) { value = client.canReportRoom() }
return RoomListState( return RoomListState(
matrixUser = matrixUser.value,
showAvatarIndicator = showAvatarIndicator,
snackbarMessage = snackbarMessage,
hasNetworkConnection = isOnline,
contextMenu = contextMenu.value, contextMenu = contextMenu.value,
declineInviteMenu = declineInviteMenu.value, declineInviteMenu = declineInviteMenu.value,
leaveRoomState = leaveRoomState, leaveRoomState = leaveRoomState,
filtersState = filtersState, filtersState = filtersState,
canReportBug = canReportBug,
searchState = searchState, searchState = searchState,
contentState = contentState, contentState = contentState,
acceptDeclineInviteState = acceptDeclineInviteState, acceptDeclineInviteState = acceptDeclineInviteState,
directLogoutState = directLogoutState,
hideInvitesAvatars = hideInvitesAvatar, hideInvitesAvatars = hideInvitesAvatar,
canReportRoom = canReportRoom, canReportRoom = canReportRoom,
eventSink = ::handleEvents, eventSink = ::handleEvents,

View file

@ -5,44 +5,34 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl.roomlist
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import io.element.android.features.home.impl.filters.RoomListFiltersState
import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.home.impl.search.RoomListSearchState
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.leaveroom.api.LeaveRoomState
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.roomlist.impl.filters.RoomListFiltersState
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.search.RoomListSearchState
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.push.api.battery.BatteryOptimizationState import io.element.android.libraries.push.api.battery.BatteryOptimizationState
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.ImmutableSet
@Immutable @Immutable
data class RoomListState( data class RoomListState(
val matrixUser: MatrixUser,
val showAvatarIndicator: Boolean,
val hasNetworkConnection: Boolean,
val snackbarMessage: SnackbarMessage?,
val contextMenu: ContextMenu, val contextMenu: ContextMenu,
val declineInviteMenu: DeclineInviteMenu, val declineInviteMenu: DeclineInviteMenu,
val leaveRoomState: LeaveRoomState, val leaveRoomState: LeaveRoomState,
val filtersState: RoomListFiltersState, val filtersState: RoomListFiltersState,
val canReportBug: Boolean,
val searchState: RoomListSearchState, val searchState: RoomListSearchState,
val contentState: RoomListContentState, val contentState: RoomListContentState,
val acceptDeclineInviteState: AcceptDeclineInviteState, val acceptDeclineInviteState: AcceptDeclineInviteState,
val directLogoutState: DirectLogoutState,
val hideInvitesAvatars: Boolean, val hideInvitesAvatars: Boolean,
val canReportRoom: Boolean, val canReportRoom: Boolean,
val eventSink: (RoomListEvents) -> Unit, val eventSink: (RoomListEvents) -> Unit,
) { ) {
val displayFilters = contentState is RoomListContentState.Rooms val displayFilters = contentState is RoomListContentState.Rooms
val displayActions = true
sealed interface ContextMenu { sealed interface ContextMenu {
data object Hidden : ContextMenu data object Hidden : ContextMenu

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl.roomlist
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId

View file

@ -5,32 +5,26 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl package io.element.android.features.home.impl.roomlist
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.home.impl.filters.RoomListFiltersState
import io.element.android.features.home.impl.filters.aRoomListFiltersState
import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.home.impl.model.RoomSummaryDisplayType
import io.element.android.features.home.impl.model.aRoomListRoomSummary
import io.element.android.features.home.impl.model.anInviteSender
import io.element.android.features.home.impl.search.RoomListSearchState
import io.element.android.features.home.impl.search.aRoomListSearchState
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteState
import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.leaveroom.api.LeaveRoomState
import io.element.android.features.leaveroom.api.aLeaveRoomState import io.element.android.features.leaveroom.api.aLeaveRoomState
import io.element.android.features.logout.api.direct.DirectLogoutState
import io.element.android.features.logout.api.direct.aDirectLogoutState
import io.element.android.features.roomlist.impl.filters.RoomListFiltersState
import io.element.android.features.roomlist.impl.filters.aRoomListFiltersState
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.model.RoomSummaryDisplayType
import io.element.android.features.roomlist.impl.model.aRoomListRoomSummary
import io.element.android.features.roomlist.impl.model.anInviteSender
import io.element.android.features.roomlist.impl.search.RoomListSearchState
import io.element.android.features.roomlist.impl.search.aRoomListSearchState
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.components.avatar.AvatarData 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.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.push.api.battery.aBatteryOptimizationState import io.element.android.libraries.push.api.battery.aBatteryOptimizationState
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -38,8 +32,6 @@ open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
override val values: Sequence<RoomListState> override val values: Sequence<RoomListState>
get() = sequenceOf( get() = sequenceOf(
aRoomListState(), aRoomListState(),
aRoomListState(snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete)),
aRoomListState(hasNetworkConnection = false),
aRoomListState(contextMenu = aContextMenuShown(roomName = null)), aRoomListState(contextMenu = aContextMenuShown(roomName = null)),
aRoomListState(contextMenu = aContextMenuShown(roomName = "A nice room name")), aRoomListState(contextMenu = aContextMenuShown(roomName = "A nice room name")),
aRoomListState(contextMenu = aContextMenuShown(isFavorite = true)), aRoomListState(contextMenu = aContextMenuShown(isFavorite = true)),
@ -53,36 +45,24 @@ open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
} }
internal fun aRoomListState( internal fun aRoomListState(
matrixUser: MatrixUser = MatrixUser(userId = UserId("@id:domain"), displayName = "User#1"),
showAvatarIndicator: Boolean = false,
hasNetworkConnection: Boolean = true,
snackbarMessage: SnackbarMessage? = null,
contextMenu: RoomListState.ContextMenu = RoomListState.ContextMenu.Hidden, contextMenu: RoomListState.ContextMenu = RoomListState.ContextMenu.Hidden,
declineInviteMenu: RoomListState.DeclineInviteMenu = RoomListState.DeclineInviteMenu.Hidden, declineInviteMenu: RoomListState.DeclineInviteMenu = RoomListState.DeclineInviteMenu.Hidden,
leaveRoomState: LeaveRoomState = aLeaveRoomState(), leaveRoomState: LeaveRoomState = aLeaveRoomState(),
searchState: RoomListSearchState = aRoomListSearchState(), searchState: RoomListSearchState = aRoomListSearchState(),
filtersState: RoomListFiltersState = aRoomListFiltersState(), filtersState: RoomListFiltersState = aRoomListFiltersState(),
canReportBug: Boolean = true,
contentState: RoomListContentState = aRoomsContentState(), contentState: RoomListContentState = aRoomsContentState(),
acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(), acceptDeclineInviteState: AcceptDeclineInviteState = anAcceptDeclineInviteState(),
directLogoutState: DirectLogoutState = aDirectLogoutState(),
hideInvitesAvatars: Boolean = false, hideInvitesAvatars: Boolean = false,
canReportRoom: Boolean = true, canReportRoom: Boolean = true,
eventSink: (RoomListEvents) -> Unit = {} eventSink: (RoomListEvents) -> Unit = {}
) = RoomListState( ) = RoomListState(
matrixUser = matrixUser,
showAvatarIndicator = showAvatarIndicator,
hasNetworkConnection = hasNetworkConnection,
snackbarMessage = snackbarMessage,
contextMenu = contextMenu, contextMenu = contextMenu,
declineInviteMenu = declineInviteMenu, declineInviteMenu = declineInviteMenu,
leaveRoomState = leaveRoomState, leaveRoomState = leaveRoomState,
filtersState = filtersState, filtersState = filtersState,
canReportBug = canReportBug,
searchState = searchState, searchState = searchState,
contentState = contentState, contentState = contentState,
acceptDeclineInviteState = acceptDeclineInviteState, acceptDeclineInviteState = acceptDeclineInviteState,
directLogoutState = directLogoutState,
hideInvitesAvatars = hideInvitesAvatars, hideInvitesAvatars = hideInvitesAvatars,
canReportRoom = canReportRoom, canReportRoom = canReportRoom,
eventSink = eventSink, eventSink = eventSink,

View file

@ -5,10 +5,10 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.search package io.element.android.features.home.impl.search
import io.element.android.features.roomlist.impl.datasource.RoomListRoomSummaryFactory import io.element.android.features.home.impl.datasource.RoomListRoomSummaryFactory
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.matrix.api.roomlist.RoomList import io.element.android.libraries.matrix.api.roomlist.RoomList
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListFilter

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.search package io.element.android.features.home.impl.search
sealed interface RoomListSearchEvents { sealed interface RoomListSearchEvents {
data object ToggleSearchVisibility : RoomListSearchEvents data object ToggleSearchVisibility : RoomListSearchEvents

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.search package io.element.android.features.home.impl.search
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect

View file

@ -5,9 +5,9 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.search package io.element.android.features.home.impl.search
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummary
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
data class RoomListSearchState( data class RoomListSearchState(

View file

@ -5,11 +5,11 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.search package io.element.android.features.home.impl.search
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.roomlist.impl.aRoomListRoomSummaryList import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.roomlist.aRoomListRoomSummaryList
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf

View file

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
package io.element.android.features.roomlist.impl.search package io.element.android.features.home.impl.search
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
@ -34,10 +34,10 @@ import androidx.compose.ui.res.stringResource
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
import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.roomlist.impl.RoomListEvents import io.element.android.features.home.impl.components.RoomSummaryRow
import io.element.android.features.roomlist.impl.components.RoomSummaryRow import io.element.android.features.home.impl.contentType
import io.element.android.features.roomlist.impl.contentType import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.roomlist.RoomListEvents
import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.modifiers.applyIf import io.element.android.libraries.designsystem.modifiers.applyIf
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="confirm_recovery_key_banner_message">"Потвърдете ключа си за възстановяване, за да запазите достъп до хранилището за ключове и историята на съобщенията си."</string>
<string name="confirm_recovery_key_banner_primary_button_title">"Въведете ключа си за възстановяване"</string>
<string name="confirm_recovery_key_banner_title">"Хранилището ви за ключове не е синхронизирано"</string>
<string name="screen_invites_decline_chat_message">"Сигурни ли сте, че искате да отхвърлите поканата за присъединяване в %1$s?"</string>
<string name="screen_invites_decline_chat_title">"Отказване на покана"</string>
<string name="screen_invites_empty_list">"Няма покани"</string>
<string name="screen_invites_invited_you">"%1$s (%2$s) ви покани"</string>
<string name="screen_roomlist_a11y_create_message">"Създаване на нов разговор или стая"</string>
<string name="screen_roomlist_empty_message">"Започнете, като изпратите съобщение на някого."</string>
<string name="screen_roomlist_empty_title">"Все още няма чатове."</string>
<string name="screen_roomlist_filter_favourites">"Любими"</string>
<string name="screen_roomlist_filter_favourites_empty_state_subtitle">"Можете да добавите чат към фаворизираните си в настройките на чата.
Засега можете да премахнете избора на филтрите, за да видите другите си чатове."</string>
<string name="screen_roomlist_filter_favourites_empty_state_title">"Все още нямате фаворизирани чатове"</string>
<string name="screen_roomlist_filter_invites">"Покани"</string>
<string name="screen_roomlist_filter_invites_empty_state_title">"Нямате чакащи покани."</string>
<string name="screen_roomlist_filter_low_priority">"Нисък приоритет"</string>
<string name="screen_roomlist_filter_mixed_empty_state_subtitle">"Можете да премахнете избора на филтрите, за да видите другите си чатове"</string>
<string name="screen_roomlist_filter_people">"Хора"</string>
<string name="screen_roomlist_filter_people_empty_state_title">"Все още нямате директни съобщения"</string>
<string name="screen_roomlist_filter_rooms">"Стаи"</string>
<string name="screen_roomlist_filter_rooms_empty_state_title">"Все още не сте в никоя стая"</string>
<string name="screen_roomlist_filter_unreads">"Непрочетени"</string>
<string name="screen_roomlist_filter_unreads_empty_state_title">"Поздравления!
Нямате непрочетени съобщения!"</string>
<string name="screen_roomlist_main_space_title">"Всички чатове"</string>
<string name="screen_roomlist_mark_as_read">"Отбелязване като прочетено"</string>
<string name="screen_roomlist_mark_as_unread">"Отбелязване като непрочетено"</string>
<string name="session_verification_banner_message">"Изглежда, че използвате ново устройство. Потвърдете с друго устройство за достъп до вашите шифровани съобщения."</string>
<string name="session_verification_banner_title">"Потвърдете, че сте вие"</string>
</resources>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_battery_optimization_content_android">"Zakažte optimalizaci baterie pro tuto aplikaci, abyste měli jistotu, že budou přijata všechna oznámení."</string>
<string name="banner_battery_optimization_submit_android">"Zakázat optimalizaci"</string>
<string name="banner_battery_optimization_title_android">"Nepřicházejí vám oznámení?"</string>
<string name="banner_set_up_recovery_content">"Vygenerujte nový klíč pro obnovení, který lze použít k obnovení historie šifrovaných zpráv v případě, že ztratíte přístup ke svým zařízením."</string> <string name="banner_set_up_recovery_content">"Vygenerujte nový klíč pro obnovení, který lze použít k obnovení historie šifrovaných zpráv v případě, že ztratíte přístup ke svým zařízením."</string>
<string name="banner_set_up_recovery_submit">"Nastavení obnovy"</string> <string name="banner_set_up_recovery_submit">"Nastavení obnovy"</string>
<string name="banner_set_up_recovery_title">"Nastavení obnovy"</string> <string name="banner_set_up_recovery_title">"Nastavení obnovy"</string>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_battery_optimization_content_android">"Deaktiver batterioptimering for denne app for at sikre, at alle notifikationer dukker op."</string>
<string name="banner_battery_optimization_submit_android">"Deaktivér optimering"</string>
<string name="banner_battery_optimization_title_android">"Modtager du ikke notifikationer?"</string>
<string name="banner_set_up_recovery_content">"Gendan din kryptografiske identitet og meddelelseshistorik med en gendannelsesnøgle, hvis du har mistet alle dine eksisterende enheder."</string>
<string name="banner_set_up_recovery_submit">"Opsæt gendannelse"</string>
<string name="banner_set_up_recovery_title">"Konfigurer gendannelse for at beskytte din konto"</string>
<string name="confirm_recovery_key_banner_message">"Bekræft din gendannelsesnøgle for at bevare adgangen til nøglelager og meddelelseshistorik."</string>
<string name="confirm_recovery_key_banner_primary_button_title">"Indtast din gendannelsesnøgle"</string>
<string name="confirm_recovery_key_banner_secondary_button_title">"Har du glemt din gendannelsesnøgle?"</string>
<string name="confirm_recovery_key_banner_title">"Dit nøglelager er ikke synkroniseret"</string>
<string name="full_screen_intent_banner_message">"For at sikre, at du aldrig går glip af et vigtigt opkald, skal du ændre dine indstillinger til at tillade underretninger i fuld skærm, når din telefon er låst."</string>
<string name="full_screen_intent_banner_title">"Gør din opkaldsoplevelse bedre"</string>
<string name="screen_invites_decline_chat_message">"Er du sikker på, at du vil afvise invitationen til at deltage i %1$s?"</string>
<string name="screen_invites_decline_chat_title">"Afvis invitation"</string>
<string name="screen_invites_decline_direct_chat_message">"Er du sikker på, at du vil afvise denne private samtale med %1$s?"</string>
<string name="screen_invites_decline_direct_chat_title">"Afvis samtale"</string>
<string name="screen_invites_empty_list">"Ingen invitationer"</string>
<string name="screen_invites_invited_you">"%1$s(%2$s ) inviterede dig"</string>
<string name="screen_migration_message">"Dette er en engangsproces, tak for din tålmodighed."</string>
<string name="screen_migration_title">"Sætter din konto op."</string>
<string name="screen_roomlist_a11y_create_message">"Opret en ny samtale eller et nyt rum"</string>
<string name="screen_roomlist_empty_message">"Kom i gang ved at sende en besked til nogen."</string>
<string name="screen_roomlist_empty_title">"Ingen samtaler endnu."</string>
<string name="screen_roomlist_filter_favourites">"Favoritter"</string>
<string name="screen_roomlist_filter_favourites_empty_state_subtitle">"Du kan tilføje en samtale til dine favoritter i samtaleindstillingerne.
For nu kan du fravælge filtre for at se dine andre samtaler"</string>
<string name="screen_roomlist_filter_favourites_empty_state_title">"Du har endnu ingen foretrukne samtaler"</string>
<string name="screen_roomlist_filter_invites">"Invitationer"</string>
<string name="screen_roomlist_filter_invites_empty_state_title">"Du har ingen afventende invitationer."</string>
<string name="screen_roomlist_filter_low_priority">"Lav prioritet"</string>
<string name="screen_roomlist_filter_mixed_empty_state_subtitle">"Du kan fravælge filtre for at se dine andre samtaler"</string>
<string name="screen_roomlist_filter_mixed_empty_state_title">"Du har ingen samtaler til dette valg"</string>
<string name="screen_roomlist_filter_people">"Mennesker"</string>
<string name="screen_roomlist_filter_people_empty_state_title">"Du har ingen DM\'er endnu"</string>
<string name="screen_roomlist_filter_rooms">"Rum"</string>
<string name="screen_roomlist_filter_rooms_empty_state_title">"Du er ikke i noget rum endnu"</string>
<string name="screen_roomlist_filter_unreads">"Ulæste"</string>
<string name="screen_roomlist_filter_unreads_empty_state_title">"Tillykke!
Du har ingen ulæste beskeder!"</string>
<string name="screen_roomlist_knock_event_sent_description">"Anmodning om at deltage sendt"</string>
<string name="screen_roomlist_main_space_title">"Samtaler"</string>
<string name="screen_roomlist_mark_as_read">"Marker som læst"</string>
<string name="screen_roomlist_mark_as_unread">"Marker som ulæst"</string>
<string name="screen_roomlist_tombstoned_room_description">"Dette rum er blevet opgraderet"</string>
<string name="session_verification_banner_message">"Det ser ud til, at du bruger en ny enhed. Bekræft med en anden enhed for at få adgang til dine krypterede meddelelser."</string>
<string name="session_verification_banner_title">"Bekræft, at det er dig"</string>
</resources>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_battery_optimization_content_android">"Απενεργοποίησε τη βελτιστοποίηση μπαταρίας για αυτήν την εφαρμογή, για να βεβαιωθείς ότι λαμβάνονται όλες οι ειδοποιήσεις."</string>
<string name="banner_battery_optimization_submit_android">"Απενεργοποίηση βελτιστοποίησης"</string>
<string name="banner_battery_optimization_title_android">"Δεν φτάνουν οι ειδοποιήσεις;"</string>
<string name="banner_set_up_recovery_content">"Δημιούργησε ένα νέο κλειδί ανάκτησης που μπορεί να χρησιμοποιηθεί για την επαναφορά του ιστορικού των κρυπτογραφημένων μηνυμάτων σου σε περίπτωση που χάσεις την πρόσβαση στις συσκευές σου."</string> <string name="banner_set_up_recovery_content">"Δημιούργησε ένα νέο κλειδί ανάκτησης που μπορεί να χρησιμοποιηθεί για την επαναφορά του ιστορικού των κρυπτογραφημένων μηνυμάτων σου σε περίπτωση που χάσεις την πρόσβαση στις συσκευές σου."</string>
<string name="banner_set_up_recovery_submit">"Ρύθμιση ανάκτησης"</string> <string name="banner_set_up_recovery_submit">"Ρύθμιση ανάκτησης"</string>
<string name="banner_set_up_recovery_title">"Ρύθμιση ανάκτησης"</string> <string name="banner_set_up_recovery_title">"Ρύθμιση ανάκτησης"</string>
@ -7,7 +10,7 @@
<string name="confirm_recovery_key_banner_primary_button_title">"Εισήγαγε το κλειδί ανάκτησης"</string> <string name="confirm_recovery_key_banner_primary_button_title">"Εισήγαγε το κλειδί ανάκτησης"</string>
<string name="confirm_recovery_key_banner_secondary_button_title">"Ξέχασες το κλειδί ανάκτησης;"</string> <string name="confirm_recovery_key_banner_secondary_button_title">"Ξέχασες το κλειδί ανάκτησης;"</string>
<string name="confirm_recovery_key_banner_title">"Ο χώρος αποθήκευσης κλειδιών σου δεν είναι συγχρονισμένος"</string> <string name="confirm_recovery_key_banner_title">"Ο χώρος αποθήκευσης κλειδιών σου δεν είναι συγχρονισμένος"</string>
<string name="full_screen_intent_banner_message">"Για να διασφαλίσεις ότι δεν θα χάσεις ποτέ μια σημαντική κλήση, άλλαξε τις ρυθμίσεις σου για να επιτρέψεις τις ειδοποιήσεις πλήρους οθόνης όταν το τηλέφωνό σου είναι κλειδωμένο."</string> <string name="full_screen_intent_banner_message">"Για να διασφαλίσετε ότι δεν θα χάσετε ποτέ μια σημαντική κλήση, αλλάξτε τις ρυθμίσεις σας ώστε να επιτρέπονται οι ειδοποιήσεις πλήρους οθόνης όταν το τηλέφωνό σας είναι κλειδωμένο."</string>
<string name="full_screen_intent_banner_title">"Βελτίωσε την εμπειρία κλήσεων"</string> <string name="full_screen_intent_banner_title">"Βελτίωσε την εμπειρία κλήσεων"</string>
<string name="screen_invites_decline_chat_message">"Σίγουρα θες να απορρίψεις την πρόσκληση συμμετοχής στο %1$s;"</string> <string name="screen_invites_decline_chat_message">"Σίγουρα θες να απορρίψεις την πρόσκληση συμμετοχής στο %1$s;"</string>
<string name="screen_invites_decline_chat_title">"Απόρριψη πρόσκλησης"</string> <string name="screen_invites_decline_chat_title">"Απόρριψη πρόσκλησης"</string>
@ -17,7 +20,7 @@
<string name="screen_invites_invited_you">"%1$s (%2$s) σέ προσκάλεσε"</string> <string name="screen_invites_invited_you">"%1$s (%2$s) σέ προσκάλεσε"</string>
<string name="screen_migration_message">"Αυτή είναι μια εφάπαξ διαδικασία, ευχαριστώ που περίμενες."</string> <string name="screen_migration_message">"Αυτή είναι μια εφάπαξ διαδικασία, ευχαριστώ που περίμενες."</string>
<string name="screen_migration_title">"Ρύθμιση του λογαριασμού σου."</string> <string name="screen_migration_title">"Ρύθμιση του λογαριασμού σου."</string>
<string name="screen_roomlist_a11y_create_message">"Δημιουργία νέας συνομιλίας ή δωματίου"</string> <string name="screen_roomlist_a11y_create_message">"Δημιουργία νέας συνομιλίας ή αίθουσας"</string>
<string name="screen_roomlist_empty_message">"Ξεκίνησε στέλνοντας μηνύματα σε κάποιον."</string> <string name="screen_roomlist_empty_message">"Ξεκίνησε στέλνοντας μηνύματα σε κάποιον."</string>
<string name="screen_roomlist_empty_title">"Δεν υπάρχουν συνομιλίες ακόμα."</string> <string name="screen_roomlist_empty_title">"Δεν υπάρχουν συνομιλίες ακόμα."</string>
<string name="screen_roomlist_filter_favourites">"Αγαπημένα"</string> <string name="screen_roomlist_filter_favourites">"Αγαπημένα"</string>
@ -31,8 +34,8 @@
<string name="screen_roomlist_filter_mixed_empty_state_title">"Δεν έχεις συνομιλίες για αυτήν την επιλογή"</string> <string name="screen_roomlist_filter_mixed_empty_state_title">"Δεν έχεις συνομιλίες για αυτήν την επιλογή"</string>
<string name="screen_roomlist_filter_people">"Άτομα"</string> <string name="screen_roomlist_filter_people">"Άτομα"</string>
<string name="screen_roomlist_filter_people_empty_state_title">"Δεν έχεις ακόμα ΠΜ"</string> <string name="screen_roomlist_filter_people_empty_state_title">"Δεν έχεις ακόμα ΠΜ"</string>
<string name="screen_roomlist_filter_rooms">"Δωμάτια"</string> <string name="screen_roomlist_filter_rooms">"Αίθουσες"</string>
<string name="screen_roomlist_filter_rooms_empty_state_title">"Δεν είσαι ακόμα σε κανένα δωμάτιο"</string> <string name="screen_roomlist_filter_rooms_empty_state_title">"Δεν είστε ακόμα σε κάποια αίθουσα"</string>
<string name="screen_roomlist_filter_unreads">"Μη αναγνωσμένα"</string> <string name="screen_roomlist_filter_unreads">"Μη αναγνωσμένα"</string>
<string name="screen_roomlist_filter_unreads_empty_state_title">"Συγχαρητήρια! <string name="screen_roomlist_filter_unreads_empty_state_title">"Συγχαρητήρια!
Δεν έχεις μη αναγνωσμένα μηνύματα!"</string> Δεν έχεις μη αναγνωσμένα μηνύματα!"</string>
@ -40,6 +43,7 @@
<string name="screen_roomlist_main_space_title">"Συνομιλίες"</string> <string name="screen_roomlist_main_space_title">"Συνομιλίες"</string>
<string name="screen_roomlist_mark_as_read">"Επισήμανση ως αναγνωσμένου"</string> <string name="screen_roomlist_mark_as_read">"Επισήμανση ως αναγνωσμένου"</string>
<string name="screen_roomlist_mark_as_unread">"Επισήμανση ως μη αναγνωσμένου"</string> <string name="screen_roomlist_mark_as_unread">"Επισήμανση ως μη αναγνωσμένου"</string>
<string name="screen_roomlist_tombstoned_room_description">"Αυτή η αίθουσα έχει αναβαθμιστεί"</string>
<string name="session_verification_banner_message">"Φαίνεται ότι χρησιμοποιείς μια νέα συσκευή. Επαλήθευσε με άλλη συσκευή για πρόσβαση στα κρυπτογραφημένα σου μηνύματα."</string> <string name="session_verification_banner_message">"Φαίνεται ότι χρησιμοποιείς μια νέα συσκευή. Επαλήθευσε με άλλη συσκευή για πρόσβαση στα κρυπτογραφημένα σου μηνύματα."</string>
<string name="session_verification_banner_title">"Επαλήθευσε ότι είσαι εσύ"</string> <string name="session_verification_banner_title">"Επαλήθευσε ότι είσαι εσύ"</string>
</resources> </resources>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_battery_optimization_content_android">"Kui tahad olla kindel, et näed õigel ajal kõiki teavitusi, siis palun lülita akukasutuse optimeerimine välja."</string>
<string name="banner_battery_optimization_submit_android">"Lülita akukasutuse optimeerimine välja"</string>
<string name="banner_battery_optimization_title_android">"Sa ei näe kõiki teavitusi?"</string>
<string name="banner_set_up_recovery_content">"Loo uus taastevõti, mida saad kasutada oma krüptitud sõnumite ajaloo taastamisel olukorras, kus kaotad ligipääsu oma seadmetele."</string> <string name="banner_set_up_recovery_content">"Loo uus taastevõti, mida saad kasutada oma krüptitud sõnumite ajaloo taastamisel olukorras, kus kaotad ligipääsu oma seadmetele."</string>
<string name="banner_set_up_recovery_submit">"Seadista andmete taastamine"</string> <string name="banner_set_up_recovery_submit">"Seadista andmete taastamine"</string>
<string name="banner_set_up_recovery_title">"Seadista taastamine"</string> <string name="banner_set_up_recovery_title">"Seadista taastamine"</string>
@ -18,6 +21,7 @@
<string name="screen_migration_message">"Tänud, et ootad - seda toimingut on vaja teha vaid üks kord."</string> <string name="screen_migration_message">"Tänud, et ootad - seda toimingut on vaja teha vaid üks kord."</string>
<string name="screen_migration_title">"Seadistame sinu kasutajakontot."</string> <string name="screen_migration_title">"Seadistame sinu kasutajakontot."</string>
<string name="screen_roomlist_a11y_create_message">"Loo uus vestlus või jututuba"</string> <string name="screen_roomlist_a11y_create_message">"Loo uus vestlus või jututuba"</string>
<string name="screen_roomlist_clear_filters">"Tühjenda filtrid"</string>
<string name="screen_roomlist_empty_message">"Alustamiseks saada kellelegi sõnum."</string> <string name="screen_roomlist_empty_message">"Alustamiseks saada kellelegi sõnum."</string>
<string name="screen_roomlist_empty_title">"Veel pole vestlusi."</string> <string name="screen_roomlist_empty_title">"Veel pole vestlusi."</string>
<string name="screen_roomlist_filter_favourites">"Lemmikud"</string> <string name="screen_roomlist_filter_favourites">"Lemmikud"</string>
@ -40,6 +44,7 @@ Sul pole ühtegi lugemata sõnumit!"</string>
<string name="screen_roomlist_main_space_title">"Vestlused"</string> <string name="screen_roomlist_main_space_title">"Vestlused"</string>
<string name="screen_roomlist_mark_as_read">"Märgi loetuks"</string> <string name="screen_roomlist_mark_as_read">"Märgi loetuks"</string>
<string name="screen_roomlist_mark_as_unread">"Märgi mitteloetuks"</string> <string name="screen_roomlist_mark_as_unread">"Märgi mitteloetuks"</string>
<string name="screen_roomlist_tombstoned_room_description">"See jututuba on uuendatud"</string>
<string name="session_verification_banner_message">"Tundub, et kasutad uut seadet. Oma krüptitud sõnumite lugemiseks verifitseeri ta mõne muu oma seadmega."</string> <string name="session_verification_banner_message">"Tundub, et kasutad uut seadet. Oma krüptitud sõnumite lugemiseks verifitseeri ta mõne muu oma seadmega."</string>
<string name="session_verification_banner_title">"Verifitseeri, et see oled sina"</string> <string name="session_verification_banner_title">"Verifitseeri, et see oled sina"</string>
</resources> </resources>

View file

@ -40,6 +40,7 @@ Sinulla ei ole lukemattomia viestejä!"</string>
<string name="screen_roomlist_main_space_title">"Keskustelut"</string> <string name="screen_roomlist_main_space_title">"Keskustelut"</string>
<string name="screen_roomlist_mark_as_read">"Merkitse luetuksi"</string> <string name="screen_roomlist_mark_as_read">"Merkitse luetuksi"</string>
<string name="screen_roomlist_mark_as_unread">"Merkitse lukemattomaksi"</string> <string name="screen_roomlist_mark_as_unread">"Merkitse lukemattomaksi"</string>
<string name="screen_roomlist_tombstoned_room_description">"Tämä huone on päivitetty"</string>
<string name="session_verification_banner_message">"Vaikuttaisi siltä, että käytät uutta laitetta. Vahvista toisella laitteella nähdäksesi salatut viestit."</string> <string name="session_verification_banner_message">"Vaikuttaisi siltä, että käytät uutta laitetta. Vahvista toisella laitteella nähdäksesi salatut viestit."</string>
<string name="session_verification_banner_title">"Vahvista, että se olet sinä"</string> <string name="session_verification_banner_title">"Vahvista, että se olet sinä"</string>
</resources> </resources>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_battery_optimization_content_android">"Désactivez loptimisation de la batterie pour cette application afin de vous assurer que toutes les notifications sont reçues."</string>
<string name="banner_battery_optimization_submit_android">"Désactiver loptimisation"</string>
<string name="banner_battery_optimization_title_android">"Ils vous manque des notifications?"</string>
<string name="banner_set_up_recovery_content">"Générez une nouvelle clé de récupération qui peut être utilisée pour restaurer lhistorique de vos messages chiffrés au cas où vous perdriez laccès à vos appareils."</string> <string name="banner_set_up_recovery_content">"Générez une nouvelle clé de récupération qui peut être utilisée pour restaurer lhistorique de vos messages chiffrés au cas où vous perdriez laccès à vos appareils."</string>
<string name="banner_set_up_recovery_submit">"Configurer la sauvegarde"</string> <string name="banner_set_up_recovery_submit">"Configurer la sauvegarde"</string>
<string name="banner_set_up_recovery_title">"Configurer la récupération"</string> <string name="banner_set_up_recovery_title">"Configurer la récupération"</string>
@ -18,6 +21,7 @@
<string name="screen_migration_message">"Il sagit dune opération ponctuelle, merci dattendre quelques instants."</string> <string name="screen_migration_message">"Il sagit dune opération ponctuelle, merci dattendre quelques instants."</string>
<string name="screen_migration_title">"Configuration de votre compte."</string> <string name="screen_migration_title">"Configuration de votre compte."</string>
<string name="screen_roomlist_a11y_create_message">"Créer une nouvelle discussion ou un nouveau salon"</string> <string name="screen_roomlist_a11y_create_message">"Créer une nouvelle discussion ou un nouveau salon"</string>
<string name="screen_roomlist_clear_filters">"Supprimer les filtres"</string>
<string name="screen_roomlist_empty_message">"Commencez par envoyer un message à quelquun."</string> <string name="screen_roomlist_empty_message">"Commencez par envoyer un message à quelquun."</string>
<string name="screen_roomlist_empty_title">"Aucune discussion pour le moment."</string> <string name="screen_roomlist_empty_title">"Aucune discussion pour le moment."</string>
<string name="screen_roomlist_filter_favourites">"Favoris"</string> <string name="screen_roomlist_filter_favourites">"Favoris"</string>
@ -40,6 +44,7 @@ Vous navez plus de messages non-lus !"</string>
<string name="screen_roomlist_main_space_title">"Conversations"</string> <string name="screen_roomlist_main_space_title">"Conversations"</string>
<string name="screen_roomlist_mark_as_read">"Marquer comme lu"</string> <string name="screen_roomlist_mark_as_read">"Marquer comme lu"</string>
<string name="screen_roomlist_mark_as_unread">"Marquer comme non lu"</string> <string name="screen_roomlist_mark_as_unread">"Marquer comme non lu"</string>
<string name="screen_roomlist_tombstoned_room_description">"Ce salon a été mis à niveau."</string>
<string name="session_verification_banner_message">"Il semblerait que vous utilisiez un nouvel appareil. Vérifiez la session avec un autre de vos appareils pour accéder à vos messages chiffrés."</string> <string name="session_verification_banner_message">"Il semblerait que vous utilisiez un nouvel appareil. Vérifiez la session avec un autre de vos appareils pour accéder à vos messages chiffrés."</string>
<string name="session_verification_banner_title">"Vérifier que cest bien vous"</string> <string name="session_verification_banner_title">"Vérifier que cest bien vous"</string>
</resources> </resources>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_battery_optimization_content_android">"Kapcsolja ki az alkalmazás akkumulátor-optimalizálását, hogy biztosan megkapja az összes értesítést."</string>
<string name="banner_battery_optimization_submit_android">"Optimalizálás letiltása"</string>
<string name="banner_battery_optimization_title_android">"Nem érkeznek meg az értesítések?"</string>
<string name="banner_set_up_recovery_content">"Hozzon létre egy új helyreállítási kulcsot, amellyel visszaállíthatja a titkosított üzenetek előzményeit, ha elveszíti az eszközökhöz való hozzáférést."</string> <string name="banner_set_up_recovery_content">"Hozzon létre egy új helyreállítási kulcsot, amellyel visszaállíthatja a titkosított üzenetek előzményeit, ha elveszíti az eszközökhöz való hozzáférést."</string>
<string name="banner_set_up_recovery_submit">"Helyreállítás beállítása"</string> <string name="banner_set_up_recovery_submit">"Helyreállítás beállítása"</string>
<string name="banner_set_up_recovery_title">"Helyreállítás beállítása a fiókja védelméhez"</string> <string name="banner_set_up_recovery_title">"Helyreállítás beállítása a fiókja védelméhez"</string>
@ -18,6 +21,7 @@
<string name="screen_migration_message">"Ez egy egyszeri folyamat, köszönjük a türelmét."</string> <string name="screen_migration_message">"Ez egy egyszeri folyamat, köszönjük a türelmét."</string>
<string name="screen_migration_title">"A fiók beállítása."</string> <string name="screen_migration_title">"A fiók beállítása."</string>
<string name="screen_roomlist_a11y_create_message">"Új beszélgetés vagy szoba létrehozása"</string> <string name="screen_roomlist_a11y_create_message">"Új beszélgetés vagy szoba létrehozása"</string>
<string name="screen_roomlist_clear_filters">"Szűrők törlése"</string>
<string name="screen_roomlist_empty_message">"Kezdje azzal, hogy üzenetet küld valakinek."</string> <string name="screen_roomlist_empty_message">"Kezdje azzal, hogy üzenetet küld valakinek."</string>
<string name="screen_roomlist_empty_title">"Még nincsenek csevegések."</string> <string name="screen_roomlist_empty_title">"Még nincsenek csevegések."</string>
<string name="screen_roomlist_filter_favourites">"Kedvencek"</string> <string name="screen_roomlist_filter_favourites">"Kedvencek"</string>
@ -40,6 +44,7 @@ Nincs olvasatlan üzenete!"</string>
<string name="screen_roomlist_main_space_title">"Összes csevegés"</string> <string name="screen_roomlist_main_space_title">"Összes csevegés"</string>
<string name="screen_roomlist_mark_as_read">"Megjelölés olvasottként"</string> <string name="screen_roomlist_mark_as_read">"Megjelölés olvasottként"</string>
<string name="screen_roomlist_mark_as_unread">"Megjelölés olvasatlanként"</string> <string name="screen_roomlist_mark_as_unread">"Megjelölés olvasatlanként"</string>
<string name="screen_roomlist_tombstoned_room_description">"A szoba verzióját frissítették"</string>
<string name="session_verification_banner_message">"Úgy tűnik, hogy új eszközt használ. Ellenőrizze egy másik eszközzel, hogy a továbbiakban elérje a titkosított üzeneteket."</string> <string name="session_verification_banner_message">"Úgy tűnik, hogy új eszközt használ. Ellenőrizze egy másik eszközzel, hogy a továbbiakban elérje a titkosított üzeneteket."</string>
<string name="session_verification_banner_title">"Ellenőrizze, hogy Ön az"</string> <string name="session_verification_banner_title">"Ellenőrizze, hogy Ön az"</string>
</resources> </resources>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_battery_optimization_content_android">"Deaktiver batterioptimalisering for denne appen for å sikre at alle varsler mottas."</string>
<string name="banner_battery_optimization_submit_android">"Deaktiver optimalisering"</string>
<string name="banner_battery_optimization_title_android">"Kommer ikke varslene frem?"</string>
<string name="banner_set_up_recovery_content">"Gjenopprett din kryptografiske identitet og meldingshistorikk med en gjenopprettingsnøkkel hvis du har mistet alle dine brukte enheter."</string> <string name="banner_set_up_recovery_content">"Gjenopprett din kryptografiske identitet og meldingshistorikk med en gjenopprettingsnøkkel hvis du har mistet alle dine brukte enheter."</string>
<string name="banner_set_up_recovery_submit">"Konfigurer gjenoppretting"</string> <string name="banner_set_up_recovery_submit">"Konfigurer gjenoppretting"</string>
<string name="banner_set_up_recovery_title">"Konfigurer gjenoppretting for å beskytte kontoen din"</string> <string name="banner_set_up_recovery_title">"Konfigurer gjenoppretting for å beskytte kontoen din"</string>
@ -40,6 +43,7 @@ Du har ingen uleste meldinger!"</string>
<string name="screen_roomlist_main_space_title">"Chatter"</string> <string name="screen_roomlist_main_space_title">"Chatter"</string>
<string name="screen_roomlist_mark_as_read">"Marker som lest"</string> <string name="screen_roomlist_mark_as_read">"Marker som lest"</string>
<string name="screen_roomlist_mark_as_unread">"Merk som ulest"</string> <string name="screen_roomlist_mark_as_unread">"Merk som ulest"</string>
<string name="screen_roomlist_tombstoned_room_description">"Dette rommet har blitt oppgradert"</string>
<string name="session_verification_banner_message">"Det ser ut til at du bruker en ny enhet. Bekreft med en annen enhet for å få tilgang til de krypterte meldingene dine."</string> <string name="session_verification_banner_message">"Det ser ut til at du bruker en ny enhet. Bekreft med en annen enhet for å få tilgang til de krypterte meldingene dine."</string>
<string name="session_verification_banner_title">"Bekreft at det er deg"</string> <string name="session_verification_banner_title">"Bekreft at det er deg"</string>
</resources> </resources>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_battery_optimization_content_android">"Desativa as otimizações de bateria para esta aplicação, de modo a garantir que todas as notificações chegam."</string>
<string name="banner_battery_optimization_submit_android">"Desativar otimizações"</string>
<string name="banner_battery_optimization_title_android">"As notificações não chegam?"</string>
<string name="banner_set_up_recovery_content">"Recupera a tua identidade criptográfica e o histórico de mensagens com uma chave de recuperação se tiveres perdido todos os teus dispositivos existentes."</string> <string name="banner_set_up_recovery_content">"Recupera a tua identidade criptográfica e o histórico de mensagens com uma chave de recuperação se tiveres perdido todos os teus dispositivos existentes."</string>
<string name="banner_set_up_recovery_submit">"Configurar recuperação"</string> <string name="banner_set_up_recovery_submit">"Configurar recuperação"</string>
<string name="banner_set_up_recovery_title">"Configurar a recuperação"</string> <string name="banner_set_up_recovery_title">"Configurar a recuperação"</string>
@ -18,6 +21,7 @@
<string name="screen_migration_message">"Este processo só acontece uma única vez, obrigado por esperares."</string> <string name="screen_migration_message">"Este processo só acontece uma única vez, obrigado por esperares."</string>
<string name="screen_migration_title">"A configurar a tua conta…"</string> <string name="screen_migration_title">"A configurar a tua conta…"</string>
<string name="screen_roomlist_a11y_create_message">"Criar uma nova conversa ou sala"</string> <string name="screen_roomlist_a11y_create_message">"Criar uma nova conversa ou sala"</string>
<string name="screen_roomlist_clear_filters">"Limpar filtros"</string>
<string name="screen_roomlist_empty_message">"Começa por enviar uma mensagem a alguém."</string> <string name="screen_roomlist_empty_message">"Começa por enviar uma mensagem a alguém."</string>
<string name="screen_roomlist_empty_title">"Ainda não tens conversas."</string> <string name="screen_roomlist_empty_title">"Ainda não tens conversas."</string>
<string name="screen_roomlist_filter_favourites">"Favoritas"</string> <string name="screen_roomlist_filter_favourites">"Favoritas"</string>
@ -40,6 +44,7 @@ Não tens nenhuma mensagem por ler!"</string>
<string name="screen_roomlist_main_space_title">"Conversas"</string> <string name="screen_roomlist_main_space_title">"Conversas"</string>
<string name="screen_roomlist_mark_as_read">"Marcar como lida"</string> <string name="screen_roomlist_mark_as_read">"Marcar como lida"</string>
<string name="screen_roomlist_mark_as_unread">"Marcar como não lida"</string> <string name="screen_roomlist_mark_as_unread">"Marcar como não lida"</string>
<string name="screen_roomlist_tombstoned_room_description">"Esta sala foi atualizada"</string>
<string name="session_verification_banner_message">"Parece que estás a utilizar um novo dispositivo. Verifica-o com um outro para poderes aceder às tuas mensagens cifradas."</string> <string name="session_verification_banner_message">"Parece que estás a utilizar um novo dispositivo. Verifica-o com um outro para poderes aceder às tuas mensagens cifradas."</string>
<string name="session_verification_banner_title">"Verifica que és tu"</string> <string name="session_verification_banner_title">"Verifica que és tu"</string>
</resources> </resources>

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