Merge remote-tracking branch 'origin/develop' into feature/fre/start_chat_with_matrix_id
This commit is contained in:
commit
4bbc2aa3c2
75 changed files with 1695 additions and 125 deletions
|
|
@ -0,0 +1,6 @@
|
|||
<?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">"Nueva sala"</string>
|
||||
<string name="screen_create_room_action_invite_people">"Invitar gente"</string>
|
||||
<string name="screen_create_room_add_people_title">"Añadir personas"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?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">"Nuova stanza"</string>
|
||||
<string name="screen_create_room_action_invite_people">"Invita persone"</string>
|
||||
<string name="screen_create_room_add_people_title">"Aggiungi persone"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?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">"Cameră nouă"</string>
|
||||
<string name="screen_create_room_action_invite_people">"Invitați persoane"</string>
|
||||
<string name="screen_create_room_add_people_title">"Adaugați persoane"</string>
|
||||
</resources>
|
||||
20
features/login/impl/src/main/res/values-es/translations.xml
Normal file
20
features/login/impl/src/main/res/values-es/translations.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_change_server_error_invalid_homeserver">"No hemos podido acceder a este servidor. Comprueba que has introducido correctamente la dirección del servidor. Si la dirección es correcta, ponte en contacto con el administrador del servidor para obtener más ayuda."</string>
|
||||
<string name="screen_change_server_error_no_sliding_sync_message">"Este servidor no soporta sliding sync."</string>
|
||||
<string name="screen_change_server_form_header">"Dirección del homeserver"</string>
|
||||
<string name="screen_change_server_form_notice">"Solo puedes conectarte a un servidor que soporte sliding sync. El administrador de tu servidor tendrá que configurarlo. %1$s"</string>
|
||||
<string name="screen_change_server_submit">"Continuar"</string>
|
||||
<string name="screen_change_server_subtitle">"¿Cuál es la dirección de tu servidor?"</string>
|
||||
<string name="screen_change_server_title">"Selecciona tu servidor"</string>
|
||||
<string name="screen_login_error_deactivated_account">"Esta cuenta ha sido desactivada."</string>
|
||||
<string name="screen_login_error_invalid_credentials">"Usuario y/o contraseña incorrectos"</string>
|
||||
<string name="screen_login_error_invalid_user_id">"Este no es un id de usuario válido. Formato esperado: \'@user:homeserver.org\'"</string>
|
||||
<string name="screen_login_error_unsupported_authentication">"El servidor seleccionado no admite contraseñas ni inicio de sesión OIDC. Póngase en contacto con su administrador o elija otro homeserver."</string>
|
||||
<string name="screen_login_form_header">"Introduce tus datos"</string>
|
||||
<string name="screen_login_password_hint">"Contraseña"</string>
|
||||
<string name="screen_login_server_header">"Donde viven tus conversaciones"</string>
|
||||
<string name="screen_login_submit">"Continuar"</string>
|
||||
<string name="screen_login_title">"¡Hola de nuevo!"</string>
|
||||
<string name="screen_login_username_hint">"Usuario"</string>
|
||||
</resources>
|
||||
20
features/login/impl/src/main/res/values-it/translations.xml
Normal file
20
features/login/impl/src/main/res/values-it/translations.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_change_server_error_invalid_homeserver">"Non siamo riusciti a raggiungere questo homserver. Verifica di aver inserito correttamente l\'URL del server domestico. Se l\'URL è corretto, contatta l\'amministratore del tuo server domestico per ulteriore assistenza."</string>
|
||||
<string name="screen_change_server_error_no_sliding_sync_message">"Questo server attualmente non supporta la sincronizzazione scorrevole."</string>
|
||||
<string name="screen_change_server_form_header">"URL dell\'homeserver"</string>
|
||||
<string name="screen_change_server_form_notice">"Puoi connetterti solo a un server esistente che supporta la sincronizzazione scorrevole. L\'amministratore del tuo server domestico dovrà configurarlo. %1$s"</string>
|
||||
<string name="screen_change_server_submit">"Continua"</string>
|
||||
<string name="screen_change_server_subtitle">"Qual è l\'indirizzo del tuo server?"</string>
|
||||
<string name="screen_change_server_title">"Seleziona il tuo server"</string>
|
||||
<string name="screen_login_error_deactivated_account">"Questo profilo è stato disattivato."</string>
|
||||
<string name="screen_login_error_invalid_credentials">"Nome utente e/o password errati"</string>
|
||||
<string name="screen_login_error_invalid_user_id">"Questo non è un identificatore utente valido. Formato previsto: \'@user:homeserver.org\'"</string>
|
||||
<string name="screen_login_error_unsupported_authentication">"L\'homeserver selezionato non supporta la password o l\'accesso OIDC. Contatta il tuo amministratore o scegli un altro homeserver."</string>
|
||||
<string name="screen_login_form_header">"Inserisci i tuoi dati"</string>
|
||||
<string name="screen_login_password_hint">"Password"</string>
|
||||
<string name="screen_login_server_header">"Dove vivono le tue conversazioni"</string>
|
||||
<string name="screen_login_submit">"Continua"</string>
|
||||
<string name="screen_login_title">"Bentornato!"</string>
|
||||
<string name="screen_login_username_hint">"Nome utente"</string>
|
||||
</resources>
|
||||
20
features/login/impl/src/main/res/values-ro/translations.xml
Normal file
20
features/login/impl/src/main/res/values-ro/translations.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_change_server_error_invalid_homeserver">"Nu am putut accesa acest homeserver. Te rugăm să verifici că ai introdus corect adresa URL a homeserver-ului. Dacă adresa URL este corectă, contactează administratorul homeserver-ului pentru ajutor suplimentar."</string>
|
||||
<string name="screen_change_server_error_no_sliding_sync_message">"Momentan acest server nu oferă suport pentru sliding sync."</string>
|
||||
<string name="screen_change_server_form_header">"Adresa URL a homeserver-ului"</string>
|
||||
<string name="screen_change_server_form_notice">"Vă putețo conecta numai la un server existent care oferă suport pentru sliding sync. Administratorul homeserver-ului dumneavoastră va trebui să îl configureze. %1$s"</string>
|
||||
<string name="screen_change_server_submit">"Continuați"</string>
|
||||
<string name="screen_change_server_subtitle">"Care este adresa serverului dumneavoastră?"</string>
|
||||
<string name="screen_change_server_title">"Selectați serverul"</string>
|
||||
<string name="screen_login_error_deactivated_account">"Acest cont a fost dezactivat."</string>
|
||||
<string name="screen_login_error_invalid_credentials">"Utilizator și/sau parolă incorecte"</string>
|
||||
<string name="screen_login_error_invalid_user_id">"Acesta nu este un identificator de utilizator valid. Format așteptat: „@user:homeserver.org”"</string>
|
||||
<string name="screen_login_error_unsupported_authentication">"Homeserver-ul selectat nu acceptă autentificarea prin parola sau OIDC. Te rugăm să contactezi administratorul sau să alegi un alt homeserver."</string>
|
||||
<string name="screen_login_form_header">"Introduceți detaliile"</string>
|
||||
<string name="screen_login_password_hint">"Parolă"</string>
|
||||
<string name="screen_login_server_header">"Locul unde trăiesc conversațiile tale"</string>
|
||||
<string name="screen_login_submit">"Continuați"</string>
|
||||
<string name="screen_login_title">"Bine ați revenit!"</string>
|
||||
<string name="screen_login_username_hint">"Utilizator"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_signout_confirmation_dialog_content">"¿Estás seguro de que quieres cerrar sesión?"</string>
|
||||
<string name="screen_signout_confirmation_dialog_submit">"Cerrar sesión"</string>
|
||||
<string name="screen_signout_confirmation_dialog_title">"Cerrar sesión"</string>
|
||||
<string name="screen_signout_in_progress_dialog_content">"Cerrando sesión…"</string>
|
||||
<string name="screen_signout_preference_item">"Cerrar sesión"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_signout_confirmation_dialog_content">"Sei sicuro di voler uscire?"</string>
|
||||
<string name="screen_signout_confirmation_dialog_submit">"Esci"</string>
|
||||
<string name="screen_signout_confirmation_dialog_title">"Esci"</string>
|
||||
<string name="screen_signout_in_progress_dialog_content">"Uscita in corso…"</string>
|
||||
<string name="screen_signout_preference_item">"Esci"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_signout_confirmation_dialog_content">"Sunteți sigur că vreți să vă deconectați?"</string>
|
||||
<string name="screen_signout_confirmation_dialog_submit">"Deconectați-vă"</string>
|
||||
<string name="screen_signout_confirmation_dialog_title">"Deconectați-vă"</string>
|
||||
<string name="screen_signout_in_progress_dialog_content">"Deconectare în curs…"</string>
|
||||
<string name="screen_signout_preference_item">"Deconectați-vă"</string>
|
||||
</resources>
|
||||
|
|
@ -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_onboarding_welcome_subtitle">"Bienvenido a la beta de %1$s. Vitaminado, para mayor rapidez y sencillez."</string>
|
||||
<string name="screen_onboarding_welcome_title">"Siéntente en tu Elemento"</string>
|
||||
</resources>
|
||||
|
|
@ -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_onboarding_welcome_subtitle">"Benvenuto nella beta di %1$s. Potenziato in velocità e semplicità."</string>
|
||||
<string name="screen_onboarding_welcome_title">"Sii nel tuo elemento"</string>
|
||||
</resources>
|
||||
|
|
@ -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_onboarding_welcome_subtitle">"Bun venit la versiunea beta a %1$s. Supraalimentat, pentru viteză și simplitate."</string>
|
||||
<string name="screen_onboarding_welcome_title">"Fii în Elementul tău"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="crash_detection_dialog_content">"%1$s se cerró inesperadamente la última vez que se lo usaste. ¿Quieres compartir un informe de error con nosotros?"</string>
|
||||
<string name="rageshake_detection_dialog_content">"Parece que sacudes el teléfono con frustración. ¿Quieres abrir la pantalla de informe de errores?"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="crash_detection_dialog_content">"%1$s si è chiuso inaspettatamente l\'ultima volta che è stato usato. Vuoi condividere con noi un rapporto sull\'arresto anomalo?"</string>
|
||||
<string name="rageshake_detection_dialog_content">"Sembra che tu stia scuotendo il telefono per la frustrazione. Vuoi aprire la schermata di segnalazione dei problemi?"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="crash_detection_dialog_content">"%1$s s-a blocat ultima dată când a fost folosit. Doriți să ne trimiteți un raport?"</string>
|
||||
<string name="rageshake_detection_dialog_content">"Se pare că scuturați telefonul de frustrare. Doriți să deschdeți ecranul de raportare a unei erori?"</string>
|
||||
</resources>
|
||||
|
|
@ -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_bug_report_attach_screenshot">"Adjuntar captura de pantalla"</string>
|
||||
<string name="screen_bug_report_contact_me">"Podéis poneros en contacto conmigo para resolver dudas relacionadas"</string>
|
||||
<string name="screen_bug_report_edit_screenshot">"Editar captura de pantalla"</string>
|
||||
<string name="screen_bug_report_editor_description">"Describe el problema. ¿Qué hiciste? ¿Qué esperabas que ocurriera? ¿Qué ocurrió en realidad? Por favor, detállalo todo lo que puedas."</string>
|
||||
<string name="screen_bug_report_editor_placeholder">"Describe el error…"</string>
|
||||
<string name="screen_bug_report_editor_supporting">"Si es posible, escriba la descripción en inglés."</string>
|
||||
<string name="screen_bug_report_include_crash_logs">"Enviar registros de fallos"</string>
|
||||
<string name="screen_bug_report_include_logs">"Enviar registros para ayudar"</string>
|
||||
<string name="screen_bug_report_include_screenshot">"Enviar captura de pantalla"</string>
|
||||
<string name="screen_bug_report_logs_description">"Para comprobar que todo funciona correctamente, se enviarán registros de fallos con su mensaje. Serán privados. Para enviar sólo tu mensaje, desactiva esta opción."</string>
|
||||
<string name="screen_bug_report_rash_logs_alert_title">"%1$s se cerró inesperadamente la última vez que se lo usaste. ¿Quieres compartir un informe de error con nosotros?"</string>
|
||||
</resources>
|
||||
|
|
@ -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_bug_report_attach_screenshot">"Allega istantanea schermo"</string>
|
||||
<string name="screen_bug_report_contact_me">"Potete contattarmi per qualsiasi altra domanda"</string>
|
||||
<string name="screen_bug_report_edit_screenshot">"Modifica istantanea schermo"</string>
|
||||
<string name="screen_bug_report_editor_description">"Descrivi il bug. Che cosa hai fatto? Cosa ti aspettavi che accadesse? Cosa è effettivamente accaduto. Si prega di inserire il maggior numero di dettagli possibile."</string>
|
||||
<string name="screen_bug_report_editor_placeholder">"Descrivi il problema…"</string>
|
||||
<string name="screen_bug_report_editor_supporting">"Se possibile, scrivere la descrizione in inglese."</string>
|
||||
<string name="screen_bug_report_include_crash_logs">"Invia i log degli arresti anomali"</string>
|
||||
<string name="screen_bug_report_include_logs">"Invia i log per aiutarci"</string>
|
||||
<string name="screen_bug_report_include_screenshot">"Invia istantanea schermo"</string>
|
||||
<string name="screen_bug_report_logs_description">"Per verificare che le cose funzionino come previsto, i log verranno inviati con il tuo messaggio. Questi saranno privati. Per inviare solo il tuo messaggio, disattiva questa impostazione."</string>
|
||||
<string name="screen_bug_report_rash_logs_alert_title">"%1$s si è chiuso inaspettatamente l\'ultima volta che è stato usato. Vuoi condividere con noi un rapporto sull\'arresto anomalo?"</string>
|
||||
</resources>
|
||||
|
|
@ -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_bug_report_attach_screenshot">"Atașați o captură de ecran"</string>
|
||||
<string name="screen_bug_report_contact_me">"Puteți să mă contactați dacă aveți întrebări suplimentare"</string>
|
||||
<string name="screen_bug_report_edit_screenshot">"Editați captura de ecran"</string>
|
||||
<string name="screen_bug_report_editor_description">"Vă rugăm să descrieți eroarea. Ce ați făcut? Ce vă aşteptați să se întâmple? Ce s-a întâmplat de fapt. Vă rugam să intrați în cât mai multe detalii cu putință."</string>
|
||||
<string name="screen_bug_report_editor_placeholder">"Descrieți eroarea…"</string>
|
||||
<string name="screen_bug_report_editor_supporting">"Dacă posibil, vă rugăm să scrieți descrierea în engleză."</string>
|
||||
<string name="screen_bug_report_include_crash_logs">"Trimiteți log-uri"</string>
|
||||
<string name="screen_bug_report_include_logs">"Trimiteți log-uri pentru a ajuta"</string>
|
||||
<string name="screen_bug_report_include_screenshot">"Trimiteți captură de ecran"</string>
|
||||
<string name="screen_bug_report_logs_description">"Pentru a verifica că lucrurile funcționează conform așteptărilor, log-uri vor fi trimise împreună cu mesajul. Acestea vor fi private. Pentru a trimite doar mesajul, dezactivați această setare."</string>
|
||||
<string name="screen_bug_report_rash_logs_alert_title">"%1$s s-a blocat ultima dată când a fost folosit. Dorești să ne trimiti un raport?"</string>
|
||||
</resources>
|
||||
|
|
@ -18,9 +18,9 @@ package io.element.android.features.roomdetails.api
|
|||
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import io.element.android.libraries.architecture.FeatureEntryPoint
|
||||
|
||||
interface RoomDetailsEntryPoint : FeatureEntryPoint {
|
||||
fun createNode(parentNode: Node, buildContext: BuildContext): Node
|
||||
|
||||
fun createNode(parentNode: Node, buildContext: BuildContext, plugins: List<Plugin>): Node
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package io.element.android.features.roomdetails.impl
|
|||
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
|
|
@ -26,7 +27,7 @@ import javax.inject.Inject
|
|||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultRoomDetailsEntryPoint @Inject constructor() : RoomDetailsEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext): Node {
|
||||
return parentNode.createNode<RoomDetailsFlowNode>(buildContext)
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, plugins: List<Plugin>): Node {
|
||||
return parentNode.createNode<RoomDetailsFlowNode>(buildContext, plugins)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,4 +16,8 @@
|
|||
|
||||
package io.element.android.features.roomdetails.impl
|
||||
|
||||
sealed interface RoomDetailsEvent
|
||||
sealed interface RoomDetailsEvent {
|
||||
data class LeaveRoom(val needsConfirmation: Boolean) : RoomDetailsEvent
|
||||
object ClearLeaveRoomWarning : RoomDetailsEvent
|
||||
object ClearError : RoomDetailsEvent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,22 +21,31 @@ import androidx.compose.runtime.LaunchedEffect
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomDetailsPresenter @Inject constructor(
|
||||
private val room: MatrixRoom,
|
||||
private val roomMembershipObserver: RoomMembershipObserver,
|
||||
) : Presenter<RoomDetailsState> {
|
||||
|
||||
@Composable
|
||||
override fun present(): RoomDetailsState {
|
||||
// fun handleEvents(event: RoomDetailsEvent) {}
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var leaveRoomWarning by remember {
|
||||
mutableStateOf<LeaveRoomWarning?>(null)
|
||||
}
|
||||
var error by remember {
|
||||
mutableStateOf<RoomDetailsError?>(null)
|
||||
}
|
||||
var memberCount: Async<Int> by remember { mutableStateOf(Async.Loading()) }
|
||||
LaunchedEffect(Unit) {
|
||||
withContext(Dispatchers.IO) {
|
||||
|
|
@ -47,6 +56,28 @@ class RoomDetailsPresenter @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
fun handleEvents(event: RoomDetailsEvent) {
|
||||
when (event) {
|
||||
is RoomDetailsEvent.LeaveRoom -> {
|
||||
if (event.needsConfirmation) {
|
||||
leaveRoomWarning = LeaveRoomWarning.computeLeaveRoomWarning(room.isPublic, memberCount)
|
||||
} else {
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
room.leave()
|
||||
.onSuccess {
|
||||
roomMembershipObserver.notifyUserLeftRoom(room.roomId)
|
||||
}.onFailure {
|
||||
error = RoomDetailsError.AlertGeneric
|
||||
}
|
||||
leaveRoomWarning = null
|
||||
}
|
||||
}
|
||||
}
|
||||
is RoomDetailsEvent.ClearLeaveRoomWarning -> leaveRoomWarning = null
|
||||
RoomDetailsEvent.ClearError -> error = null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return RoomDetailsState(
|
||||
roomId = room.roomId.value,
|
||||
|
|
@ -56,7 +87,9 @@ class RoomDetailsPresenter @Inject constructor(
|
|||
roomTopic = room.topic,
|
||||
memberCount = memberCount,
|
||||
isEncrypted = room.isEncrypted,
|
||||
// eventSink = ::handleEvents
|
||||
displayLeaveRoomWarning = leaveRoomWarning,
|
||||
error = error,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
package io.element.android.features.roomdetails.impl
|
||||
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.isLoading
|
||||
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
|
||||
data class RoomDetailsState(
|
||||
val roomId: String,
|
||||
|
|
@ -26,5 +29,27 @@ data class RoomDetailsState(
|
|||
val roomTopic: String?,
|
||||
val memberCount: Async<Int>,
|
||||
val isEncrypted: Boolean,
|
||||
// val eventSink: (RoomDetailsEvent) -> Unit
|
||||
val displayLeaveRoomWarning: LeaveRoomWarning?,
|
||||
val error: RoomDetailsError?,
|
||||
val eventSink: (RoomDetailsEvent) -> Unit
|
||||
)
|
||||
|
||||
sealed class LeaveRoomWarning {
|
||||
object Generic : LeaveRoomWarning()
|
||||
object PrivateRoom : LeaveRoomWarning()
|
||||
object LastUserInRoom : LeaveRoomWarning()
|
||||
|
||||
companion object {
|
||||
fun computeLeaveRoomWarning(isPublic: Boolean, memberCount: Async<Int>): LeaveRoomWarning {
|
||||
return when {
|
||||
!isPublic -> PrivateRoom
|
||||
(memberCount as? Async.Success<Int>)?.state == 1 -> LastUserInRoom
|
||||
else -> Generic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface RoomDetailsError {
|
||||
object AlertGeneric : RoomDetailsError
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,5 +43,7 @@ fun aRoomDetailsState() = RoomDetailsState(
|
|||
"|| MAI iki/Marketing...",
|
||||
memberCount = Async.Success(32),
|
||||
isEncrypted = true,
|
||||
// eventSink = {}
|
||||
displayLeaveRoomWarning = null,
|
||||
error = null,
|
||||
eventSink = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ 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.AvatarSize
|
||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
|
|
@ -57,6 +59,7 @@ import io.element.android.libraries.designsystem.theme.LocalColors
|
|||
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.TopAppBar
|
||||
import io.element.android.libraries.ui.strings.R as StringR
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -101,7 +104,24 @@ fun RoomDetailsView(
|
|||
SecuritySection()
|
||||
}
|
||||
|
||||
OtherActionsSection()
|
||||
OtherActionsSection(onLeaveRoom = {
|
||||
state.eventSink(RoomDetailsEvent.LeaveRoom(needsConfirmation = true))
|
||||
})
|
||||
|
||||
if (state.displayLeaveRoomWarning != null) {
|
||||
ConfirmLeaveRoomDialog(
|
||||
leaveRoomWarning = state.displayLeaveRoomWarning,
|
||||
onConfirmLeave = { state.eventSink(RoomDetailsEvent.LeaveRoom(needsConfirmation = false)) },
|
||||
onDismiss = { state.eventSink(RoomDetailsEvent.ClearLeaveRoomWarning) }
|
||||
)
|
||||
}
|
||||
|
||||
if (state.error != null) {
|
||||
ErrorDialog(
|
||||
content = stringResource(StringR.string.error_unknown),
|
||||
onDismiss = { state.eventSink(RoomDetailsEvent.ClearError) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -189,16 +209,38 @@ internal fun SecuritySection(modifier: Modifier = Modifier) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
internal fun OtherActionsSection(modifier: Modifier = Modifier) {
|
||||
internal fun OtherActionsSection(onLeaveRoom: () -> Unit, modifier: Modifier = Modifier) {
|
||||
PreferenceCategory(showDivider = false, modifier = modifier) {
|
||||
PreferenceText(
|
||||
title = stringResource(R.string.screen_room_details_leave_room_title),
|
||||
icon = ImageVector.vectorResource(R.drawable.ic_door_open),
|
||||
tintColor = LocalColors.current.textActionCritical,
|
||||
onClick = onLeaveRoom,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun ConfirmLeaveRoomDialog(
|
||||
leaveRoomWarning: LeaveRoomWarning,
|
||||
onConfirmLeave: () -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
val content = stringResource(
|
||||
when (leaveRoomWarning) {
|
||||
LeaveRoomWarning.PrivateRoom -> StringR.string.leave_room_alert_private_subtitle
|
||||
LeaveRoomWarning.LastUserInRoom -> StringR.string.leave_room_alert_empty_subtitle
|
||||
LeaveRoomWarning.Generic -> StringR.string.leave_room_alert_subtitle
|
||||
}
|
||||
)
|
||||
ConfirmationDialog(
|
||||
content = content,
|
||||
submitText = stringResource(StringR.string.action_leave),
|
||||
onSubmitClicked = onConfirmLeave,
|
||||
onDismiss = onDismiss,
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun RoomDetailsLightPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) =
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<plurals name="screen_room_member_list_header_title">
|
||||
<item quantity="one">"Una persona"</item>
|
||||
<item quantity="other">"%1$d personas"</item>
|
||||
</plurals>
|
||||
<string name="screen_dm_details_block_alert_action">"Bloquear"</string>
|
||||
<string name="screen_dm_details_block_alert_description">"Los usuarios bloqueados no podrán enviarte mensajes y se ocultarán todos sus mensajes. Puedes revertir esta acción en cualquier momento."</string>
|
||||
<string name="screen_dm_details_block_user">"Bloquear usuario"</string>
|
||||
<string name="screen_dm_details_unblock_alert_action">"Desbloquear"</string>
|
||||
<string name="screen_dm_details_unblock_alert_description">"Al desbloquear al usuario, podrás volver a ver todos sus mensajes."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Desbloquear usuario"</string>
|
||||
<string name="screen_room_details_encryption_enabled_subtitle">"Los mensajes están protegidos con \"candados\". Sólo tú y los destinatarios tenéis las llaves únicas para abrirlos."</string>
|
||||
<string name="screen_room_details_encryption_enabled_title">"Cifrado de mensajes activado"</string>
|
||||
<string name="screen_room_details_invite_people_title">"Invitar a otras personas"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Salir de la sala"</string>
|
||||
<string name="screen_room_details_people_title">"Personas"</string>
|
||||
<string name="screen_room_details_security_title">"Seguridad"</string>
|
||||
<string name="screen_room_details_share_room_title">"Compartir sala"</string>
|
||||
<string name="screen_room_details_topic_title">"Tema"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<plurals name="screen_room_member_list_header_title">
|
||||
<item quantity="one">"1 persona"</item>
|
||||
<item quantity="other">"%1$d persone"</item>
|
||||
</plurals>
|
||||
<string name="screen_dm_details_block_alert_action">"Blocca"</string>
|
||||
<string name="screen_dm_details_block_alert_description">"Gli utenti bloccati non saranno in grado di inviarti messaggi e tutti i loro messaggi saranno nascosti. Potrai annullare questa azione in qualsiasi momento."</string>
|
||||
<string name="screen_dm_details_block_user">"Blocca utente"</string>
|
||||
<string name="screen_dm_details_unblock_alert_action">"Sblocca"</string>
|
||||
<string name="screen_dm_details_unblock_alert_description">"Dopo aver sbloccato l\'utente, potrai vedere nuovamente tutti i suoi messaggi."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Sblocca utente"</string>
|
||||
<string name="screen_room_details_encryption_enabled_subtitle">"I messaggi sono protetti da lucchetti. Solo tu e i destinatari avete le chiavi univoche per sbloccarli."</string>
|
||||
<string name="screen_room_details_encryption_enabled_title">"Crittografia messaggi abilitata"</string>
|
||||
<string name="screen_room_details_invite_people_title">"Invita persone"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Esci dalla stanza"</string>
|
||||
<string name="screen_room_details_people_title">"Persone"</string>
|
||||
<string name="screen_room_details_security_title">"Sicurezza"</string>
|
||||
<string name="screen_room_details_share_room_title">"Condividi stanza"</string>
|
||||
<string name="screen_room_details_topic_title">"Oggetto"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<plurals name="screen_room_member_list_header_title">
|
||||
<item quantity="one">"o persoană"</item>
|
||||
<item quantity="few"></item>
|
||||
<item quantity="other">"%1$d persoane"</item>
|
||||
</plurals>
|
||||
<string name="screen_dm_details_block_alert_action">"Blocați"</string>
|
||||
<string name="screen_dm_details_block_alert_description">"Utilizatorii blocați nu vă vor putea trimite mesaje și toate mesajele lor vor fi ascunse. Puteți anula această acțiune oricând."</string>
|
||||
<string name="screen_dm_details_block_user">"Blocați utilizatorul"</string>
|
||||
<string name="screen_dm_details_unblock_alert_action">"Deblocați"</string>
|
||||
<string name="screen_dm_details_unblock_alert_description">"La deblocarea utilizatorului, veți putea vedea din nou toate mesajele de la acesta."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Deblocați utilizatorul"</string>
|
||||
<string name="screen_room_details_encryption_enabled_subtitle">"Mesajele sunt securizate cu încuietori. Doar dumneavoastră și destinatarii aveți cheile unice pentru a le debloca."</string>
|
||||
<string name="screen_room_details_encryption_enabled_title">"Criptarea mesajelor este activată"</string>
|
||||
<string name="screen_room_details_invite_people_title">"Invitați persoane"</string>
|
||||
<string name="screen_room_details_leave_room_title">"Părăsiți camera"</string>
|
||||
<string name="screen_room_details_people_title">"Persoane"</string>
|
||||
<string name="screen_room_details_security_title">"Securitate"</string>
|
||||
<string name="screen_room_details_share_room_title">"Partajați camera"</string>
|
||||
<string name="screen_room_details_topic_title">"Subiect"</string>
|
||||
</resources>
|
||||
|
|
@ -4,6 +4,12 @@
|
|||
<item quantity="one">"1 person"</item>
|
||||
<item quantity="other">"%1$d people"</item>
|
||||
</plurals>
|
||||
<string name="screen_dm_details_block_alert_action">"Block"</string>
|
||||
<string name="screen_dm_details_block_alert_description">"Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime."</string>
|
||||
<string name="screen_dm_details_block_user">"Block user"</string>
|
||||
<string name="screen_dm_details_unblock_alert_action">"Unblock"</string>
|
||||
<string name="screen_dm_details_unblock_alert_description">"On unblocking the user, you will be able to see all messages by them again."</string>
|
||||
<string name="screen_dm_details_unblock_user">"Unblock user"</string>
|
||||
<string name="screen_room_details_encryption_enabled_subtitle">"Messages are secured with locks. Only you and the recipients have the unique keys to unlock them."</string>
|
||||
<string name="screen_room_details_encryption_enabled_title">"Message encryption enabled"</string>
|
||||
<string name="screen_room_details_invite_people_title">"Invite people"</string>
|
||||
|
|
|
|||
|
|
@ -20,21 +20,37 @@ import app.cash.molecule.RecompositionClock
|
|||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth
|
||||
import io.element.android.features.roomdetails.impl.LeaveRoomWarning
|
||||
import io.element.android.features.roomdetails.impl.RoomDetailsEvent
|
||||
import io.element.android.features.roomdetails.impl.RoomDetailsPresenter
|
||||
import io.element.android.libraries.architecture.Async
|
||||
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.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipState
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
class RoomDetailsPresenterTests {
|
||||
|
||||
private val roomMembershipObserver = RoomMembershipObserver(A_SESSION_ID)
|
||||
|
||||
@Test
|
||||
fun `present - initial state is created from room info`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = RoomDetailsPresenter(room)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -53,7 +69,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - room member count is calculated asynchronously`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = RoomDetailsPresenter(room)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -68,7 +84,7 @@ class RoomDetailsPresenterTests {
|
|||
@Test
|
||||
fun `present - initial state with no room name`() = runTest {
|
||||
val room = aMatrixRoom(name = null)
|
||||
val presenter = RoomDetailsPresenter(room)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -84,7 +100,7 @@ class RoomDetailsPresenterTests {
|
|||
val room = aMatrixRoom(name = null).apply {
|
||||
givenFetchMemberResult(Result.failure(Throwable()))
|
||||
}
|
||||
val presenter = RoomDetailsPresenter(room)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -94,6 +110,100 @@ class RoomDetailsPresenterTests {
|
|||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - Leave with confirmation on private room shows a specific warning`() = runTest {
|
||||
val room = aMatrixRoom(isPublic = false)
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
// Allow room member count to load
|
||||
skipItems(1)
|
||||
|
||||
initialState.eventSink(RoomDetailsEvent.LeaveRoom(needsConfirmation = true))
|
||||
val confirmationState = awaitItem()
|
||||
Truth.assertThat(confirmationState.displayLeaveRoomWarning).isEqualTo(LeaveRoomWarning.PrivateRoom)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - Leave with confirmation on empty room shows a specific warning`() = runTest {
|
||||
val room = aMatrixRoom(members = listOf(aRoomMember()))
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
// Allow room member count to load
|
||||
skipItems(1)
|
||||
|
||||
initialState.eventSink(RoomDetailsEvent.LeaveRoom(needsConfirmation = true))
|
||||
val confirmationState = awaitItem()
|
||||
Truth.assertThat(confirmationState.displayLeaveRoomWarning).isEqualTo(LeaveRoomWarning.LastUserInRoom)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - Leave with confirmation shows a generic warning`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
// Allow room member count to load
|
||||
skipItems(1)
|
||||
|
||||
initialState.eventSink(RoomDetailsEvent.LeaveRoom(needsConfirmation = true))
|
||||
val confirmationState = awaitItem()
|
||||
Truth.assertThat(confirmationState.displayLeaveRoomWarning).isEqualTo(LeaveRoomWarning.Generic)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - Leave without confirmation leaves the room`() = runTest {
|
||||
val room = aMatrixRoom()
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
// Allow room member count to load
|
||||
skipItems(1)
|
||||
|
||||
initialState.eventSink(RoomDetailsEvent.LeaveRoom(needsConfirmation = false))
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
|
||||
// Membership observer should receive a 'left room' change
|
||||
roomMembershipObserver.updates.take(1)
|
||||
.onEach { update -> Truth.assertThat(update.change).isEqualTo(MembershipChange.LEFT) }
|
||||
.collect()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - ClearError removes any error present`() = runTest {
|
||||
val room = aMatrixRoom().apply {
|
||||
givenLeaveRoomError(Throwable())
|
||||
}
|
||||
val presenter = RoomDetailsPresenter(room, roomMembershipObserver)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
// Allow room member count to load
|
||||
skipItems(1)
|
||||
|
||||
initialState.eventSink(RoomDetailsEvent.LeaveRoom(needsConfirmation = false))
|
||||
val errorState = awaitItem()
|
||||
Truth.assertThat(errorState.error).isNotNull()
|
||||
errorState.eventSink(RoomDetailsEvent.ClearError)
|
||||
Truth.assertThat(awaitItem().error).isNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun aMatrixRoom(
|
||||
|
|
@ -104,6 +214,7 @@ fun aMatrixRoom(
|
|||
avatarUrl: String? = "https://matrix.org/avatar.jpg",
|
||||
members: List<RoomMember> = emptyList(),
|
||||
isEncrypted: Boolean = true,
|
||||
isPublic: Boolean = true,
|
||||
) = FakeMatrixRoom(
|
||||
roomId = roomId,
|
||||
name = name,
|
||||
|
|
@ -112,4 +223,23 @@ fun aMatrixRoom(
|
|||
avatarUrl = avatarUrl,
|
||||
members = members,
|
||||
isEncrypted = isEncrypted,
|
||||
isPublic = isPublic,
|
||||
)
|
||||
|
||||
fun aRoomMember(
|
||||
userId: UserId = A_USER_ID,
|
||||
displayName: String? = null,
|
||||
avatarUrl: String? = null,
|
||||
membership: RoomMembershipState = RoomMembershipState.JOIN,
|
||||
isNameAmbiguous: Boolean = false,
|
||||
powerLevel: Long = 0L,
|
||||
normalizedPowerLevel: Long = 0L
|
||||
) = RoomMember(
|
||||
userId = userId.value,
|
||||
displayName = displayName,
|
||||
avatarUrl = avatarUrl,
|
||||
membership = membership,
|
||||
isNameAmbiguous = isNameAmbiguous,
|
||||
powerLevel = powerLevel,
|
||||
normalizedPowerLevel = normalizedPowerLevel,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -20,5 +20,4 @@ sealed interface RoomListEvents {
|
|||
data class UpdateFilter(val newFilter: String) : RoomListEvents
|
||||
data class UpdateVisibleRange(val range: IntRange) : RoomListEvents
|
||||
object DismissRequestVerificationPrompt : RoomListEvents
|
||||
object ClearSuccessfulVerificationMessage : RoomListEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,12 +34,14 @@ import io.element.android.libraries.core.extensions.orEmpty
|
|||
import io.element.android.libraries.dateformatter.api.LastMessageTimestampFormatter
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
|
||||
import io.element.android.libraries.designsystem.utils.handleSnackbarMessage
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||
import io.element.android.libraries.matrix.api.room.RoomSummary
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
|
||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -56,8 +58,11 @@ class RoomListPresenter @Inject constructor(
|
|||
private val lastMessageTimestampFormatter: LastMessageTimestampFormatter,
|
||||
private val roomLastMessageFormatter: RoomLastMessageFormatter,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
private val snackbarDispatcher: SnackbarDispatcher,
|
||||
) : Presenter<RoomListState> {
|
||||
|
||||
private val roomMembershipObserver: RoomMembershipObserver = client.roomMembershipObserver()
|
||||
|
||||
@Composable
|
||||
override fun present(): RoomListState {
|
||||
val matrixUser: MutableState<MatrixUser?> = remember {
|
||||
|
|
@ -86,19 +91,11 @@ class RoomListPresenter @Inject constructor(
|
|||
derivedStateOf { sessionVerifiedStatus == SessionVerifiedStatus.NotVerified && !verificationPromptDismissed }
|
||||
}
|
||||
|
||||
// Current verification flow status, if any (initial, requesting, accepted, etc.)
|
||||
val currentVerificationFlowStatus by sessionVerificationService.verificationFlowState.collectAsState()
|
||||
// We only care about the 'Finished' state to display the 'verification success' message
|
||||
val presentVerificationSuccessfulMessage = remember {
|
||||
derivedStateOf { currentVerificationFlowStatus == VerificationFlowState.Finished }
|
||||
}
|
||||
|
||||
fun handleEvents(event: RoomListEvents) {
|
||||
when (event) {
|
||||
is RoomListEvents.UpdateFilter -> filter = event.newFilter
|
||||
is RoomListEvents.UpdateVisibleRange -> updateVisibleRange(event.range)
|
||||
RoomListEvents.DismissRequestVerificationPrompt -> verificationPromptDismissed = true
|
||||
RoomListEvents.ClearSuccessfulVerificationMessage -> sessionVerificationService.reset()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,12 +103,14 @@ class RoomListPresenter @Inject constructor(
|
|||
filteredRoomSummaries.value = updateFilteredRoomSummaries(roomSummaries, filter)
|
||||
}
|
||||
|
||||
val snackbarMessage = handleSnackbarMessage(snackbarDispatcher)
|
||||
|
||||
return RoomListState(
|
||||
matrixUser = matrixUser.value,
|
||||
roomList = filteredRoomSummaries.value,
|
||||
filter = filter,
|
||||
presentVerificationSuccessfulMessage = presentVerificationSuccessfulMessage.value,
|
||||
displayVerificationPrompt = displayVerificationPrompt,
|
||||
snackbarMessage = snackbarMessage,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package io.element.android.features.roomlist.impl
|
|||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
||||
import io.element.android.libraries.designsystem.utils.SnackbarMessage
|
||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ data class RoomListState(
|
|||
val matrixUser: MatrixUser?,
|
||||
val roomList: ImmutableList<RoomListRoomSummary>,
|
||||
val filter: String,
|
||||
val presentVerificationSuccessfulMessage: Boolean,
|
||||
val displayVerificationPrompt: Boolean,
|
||||
val snackbarMessage: SnackbarMessage?,
|
||||
val eventSink: (RoomListEvents) -> Unit
|
||||
)
|
||||
|
|
|
|||
|
|
@ -20,17 +20,19 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
|||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryPlaceholders
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.utils.SnackbarMessage
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import io.element.android.libraries.ui.strings.R as StringR
|
||||
|
||||
open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
|
||||
override val values: Sequence<RoomListState>
|
||||
get() = sequenceOf(
|
||||
aRoomListState(),
|
||||
aRoomListState().copy(displayVerificationPrompt = true),
|
||||
aRoomListState().copy(presentVerificationSuccessfulMessage = true),
|
||||
aRoomListState().copy(snackbarMessage = SnackbarMessage(StringR.string.common_verification_complete)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +41,7 @@ internal fun aRoomListState() = RoomListState(
|
|||
roomList = aRoomListRoomSummaryList(),
|
||||
filter = "filter",
|
||||
eventSink = {},
|
||||
presentVerificationSuccessfulMessage = false,
|
||||
snackbarMessage = null,
|
||||
displayVerificationPrompt = false,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -40,10 +40,11 @@ import androidx.compose.material3.SnackbarHostState
|
|||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
|
|
@ -67,6 +68,7 @@ import io.element.android.libraries.designsystem.theme.components.Surface
|
|||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.LogCompositions
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import kotlinx.coroutines.launch
|
||||
import io.element.android.libraries.designsystem.R as DrawableR
|
||||
import io.element.android.libraries.ui.strings.R as StringR
|
||||
|
||||
|
|
@ -130,14 +132,18 @@ fun RoomListContent(
|
|||
}
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val verificationCompleteMessage = stringResource(StringR.string.common_verification_complete)
|
||||
LaunchedEffect(state.presentVerificationSuccessfulMessage) {
|
||||
if (state.presentVerificationSuccessfulMessage) {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = verificationCompleteMessage,
|
||||
duration = SnackbarDuration.Short,
|
||||
)
|
||||
state.eventSink(RoomListEvents.ClearSuccessfulVerificationMessage)
|
||||
val snackbarMessageText = if (state.snackbarMessage != null ) {
|
||||
stringResource(state.snackbarMessage.messageResId)
|
||||
} else null
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
if (snackbarMessageText != null) {
|
||||
SideEffect {
|
||||
coroutineScope.launch {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = snackbarMessageText,
|
||||
duration = SnackbarDuration.Short,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_roomlist_a11y_create_message">"Crear una nueva conversación o sala"</string>
|
||||
<string name="screen_roomlist_main_space_title">"Todos los chats"</string>
|
||||
<string name="session_verification_banner_message">"Parece que estás usando un nuevo dispositivo. Verifica que eres tú para acceder a tus mensajes cifrados."</string>
|
||||
<string name="session_verification_banner_title">"Accede a tu historial de mensajes"</string>
|
||||
<string name="state_event_avatar_changed_too">"(el avatar también cambió)"</string>
|
||||
<string name="state_event_avatar_url_changed">"%1$s cambió su avatar"</string>
|
||||
<string name="state_event_avatar_url_changed_by_you">"Cambiaste tu avatar"</string>
|
||||
<string name="state_event_display_name_changed_from">"%1$s cambió su nombre de %2$s a %3$s"</string>
|
||||
<string name="state_event_display_name_changed_from_by_you">"Cambiaste tu nombre de %1$s a %2$s"</string>
|
||||
<string name="state_event_display_name_removed">"%1$s eliminó su nombre (era %2$s)"</string>
|
||||
<string name="state_event_display_name_removed_by_you">"Eliminaste tu nombre (era %1$s)"</string>
|
||||
<string name="state_event_display_name_set">"%1$s cambió su nombre a %2$s"</string>
|
||||
<string name="state_event_display_name_set_by_you">"Cambiaste tu nombre a %1$s"</string>
|
||||
<string name="state_event_room_avatar_changed">"%1$s cambió el avatar de la sala"</string>
|
||||
<string name="state_event_room_avatar_changed_by_you">"Cambiaste el avatar de la sala"</string>
|
||||
<string name="state_event_room_avatar_removed">"%1$s eliminó el avatar de la sala"</string>
|
||||
<string name="state_event_room_avatar_removed_by_you">"Eliminaste el avatar de la sala"</string>
|
||||
<string name="state_event_room_ban">"%1$s expulsó permanentemente a %2$s"</string>
|
||||
<string name="state_event_room_ban_by_you">"Expulsaste permanentemente a %1$s"</string>
|
||||
<string name="state_event_room_created">"%1$s creó la sala"</string>
|
||||
<string name="state_event_room_created_by_you">"Tú creaste la sala"</string>
|
||||
<string name="state_event_room_invite">"%1$s invitó a %2$s"</string>
|
||||
<string name="state_event_room_invite_accepted">"%1$s aceptó la invitación"</string>
|
||||
<string name="state_event_room_invite_accepted_by_you">"Aceptaste la invitación"</string>
|
||||
<string name="state_event_room_invite_by_you">"Invitaste a %1$s"</string>
|
||||
<string name="state_event_room_invite_you">"%1$s te invitó."</string>
|
||||
<string name="state_event_room_join">"%1$s se unió a la sala"</string>
|
||||
<string name="state_event_room_join_by_you">"Te uniste a la sala"</string>
|
||||
<string name="state_event_room_knock">"%1$s solicitó unirse"</string>
|
||||
<string name="state_event_room_knock_accepted">"%1$s permitió que %2$s se uniera"</string>
|
||||
<string name="state_event_room_knock_accepted_by_you">"%1$s te permitió unirte"</string>
|
||||
<string name="state_event_room_knock_by_you">"Solicitaste unirte"</string>
|
||||
<string name="state_event_room_knock_denied">"%1$s rechazó la solicitud de %2$s para unirse"</string>
|
||||
<string name="state_event_room_knock_denied_by_you">"Rechazaste la solicitud de %1$s para unirte"</string>
|
||||
<string name="state_event_room_knock_denied_you">"%1$s rechazó su solicitud para unirte"</string>
|
||||
<string name="state_event_room_knock_retracted">"%1$s ya no está interesado en unirse"</string>
|
||||
<string name="state_event_room_knock_retracted_by_you">"Cancelaste tu solicitud de unirte"</string>
|
||||
<string name="state_event_room_leave">"%1$s salió de la sala"</string>
|
||||
<string name="state_event_room_leave_by_you">"Saliste de la sala"</string>
|
||||
<string name="state_event_room_name_changed">"%1$s cambió el nombre de la sala a: %2$s"</string>
|
||||
<string name="state_event_room_name_changed_by_you">"Cambiaste el nombre de la sala a: %1$s"</string>
|
||||
<string name="state_event_room_name_removed">"%1$s eliminó el nombre de la sala"</string>
|
||||
<string name="state_event_room_name_removed_by_you">"Eliminaste el nombre de la sala"</string>
|
||||
<string name="state_event_room_reject">"%1$s rechazó la invitación"</string>
|
||||
<string name="state_event_room_reject_by_you">"Rechazaste la invitación"</string>
|
||||
<string name="state_event_room_remove">"%1$s echó a %2$s"</string>
|
||||
<string name="state_event_room_remove_by_you">"Echaste a %1$s"</string>
|
||||
<string name="state_event_room_third_party_invite">"%1$s envió una invitación a %2$s para unirse a la sala"</string>
|
||||
<string name="state_event_room_third_party_invite_by_you">"Enviaste una invitación a %1$s para unirse a la sala"</string>
|
||||
<string name="state_event_room_third_party_revoked_invite">"%1$s revocó la invitación a %2$s para unirse a la sala"</string>
|
||||
<string name="state_event_room_third_party_revoked_invite_by_you">"Revocaste la invitación de %1$s para unirse a la sala"</string>
|
||||
<string name="state_event_room_topic_changed">"%1$s cambió el tema a: %2$s"</string>
|
||||
<string name="state_event_room_topic_changed_by_you">"Cambiaste el tema a: %1$s"</string>
|
||||
<string name="state_event_room_topic_removed">"%1$s eliminó el tema de la sala"</string>
|
||||
<string name="state_event_room_topic_removed_by_you">"Eliminaste el tema de la sala"</string>
|
||||
<string name="state_event_room_unban">"%1$s readmitió a %2$s"</string>
|
||||
<string name="state_event_room_unban_by_you">"Readmitiste a %1$s"</string>
|
||||
<string name="state_event_room_unknown_membership_change">"%1$s realizó un cambio desconocido en su membresía"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_roomlist_a11y_create_message">"Crea una nuova conversazione o stanza"</string>
|
||||
<string name="screen_roomlist_main_space_title">"Tutte le conversazioni"</string>
|
||||
<string name="session_verification_banner_message">"Sembra che tu stia utilizzando un nuovo dispositivo. Verifica di essere tu per accedere ai tuoi messaggi crittografati."</string>
|
||||
<string name="session_verification_banner_title">"Accedi alla cronologia dei messaggi"</string>
|
||||
<string name="state_event_avatar_changed_too">"(anche l\'avatar è stato cambiato)"</string>
|
||||
<string name="state_event_avatar_url_changed">"%1$s ha cambiato il proprio avatar"</string>
|
||||
<string name="state_event_avatar_url_changed_by_you">"Hai cambiato il tuo avatar"</string>
|
||||
<string name="state_event_display_name_changed_from">"%1$s ha cambiato il proprio nome visualizzato da %2$s a %3$s"</string>
|
||||
<string name="state_event_display_name_changed_from_by_you">"Hai cambiato il tuo nome visualizzato da %1$s a %2$s"</string>
|
||||
<string name="state_event_display_name_removed">"%1$s ha rimosso il proprio nome visualizzato (era %2$s)"</string>
|
||||
<string name="state_event_display_name_removed_by_you">"Hai rimosso il tuo nome visualizzato (era %1$s)"</string>
|
||||
<string name="state_event_display_name_set">"%1$s ha impostato il proprio nome visualizzato su %2$s"</string>
|
||||
<string name="state_event_display_name_set_by_you">"Hai impostato il tuo nome visualizzato su %1$s"</string>
|
||||
<string name="state_event_room_avatar_changed">"%1$s ha cambiato l\'avatar della stanza"</string>
|
||||
<string name="state_event_room_avatar_changed_by_you">"Hai cambiato l\'avatar della stanza"</string>
|
||||
<string name="state_event_room_avatar_removed">"%1$s ha rimosso l\'avatar della stanza"</string>
|
||||
<string name="state_event_room_avatar_removed_by_you">"Hai rimosso l\'avatar della stanza"</string>
|
||||
<string name="state_event_room_ban">"%1$s ha rimosso %2$s"</string>
|
||||
<string name="state_event_room_ban_by_you">"Hai rimosso %1$s"</string>
|
||||
<string name="state_event_room_created">"%1$s ha creato la stanza"</string>
|
||||
<string name="state_event_room_created_by_you">"Hai creato la stanza"</string>
|
||||
<string name="state_event_room_invite">"%1$s ha invitato %2$s"</string>
|
||||
<string name="state_event_room_invite_accepted">"%1$s ha accettato l\'invito"</string>
|
||||
<string name="state_event_room_invite_accepted_by_you">"Hai accettato l\'invito"</string>
|
||||
<string name="state_event_room_invite_by_you">"Hai invitato %1$s"</string>
|
||||
<string name="state_event_room_invite_you">"%1$s ti ha invitato"</string>
|
||||
<string name="state_event_room_join">"%1$s si è unito alla stanza"</string>
|
||||
<string name="state_event_room_join_by_you">"Ti sei unito alla stanza"</string>
|
||||
<string name="state_event_room_knock">"%1$s ha chiesto di unirsi"</string>
|
||||
<string name="state_event_room_knock_accepted">"%1$s ha permesso a %2$s di unirsi"</string>
|
||||
<string name="state_event_room_knock_accepted_by_you">"%1$s ti ha permesso di unirti"</string>
|
||||
<string name="state_event_room_knock_by_you">"Hai richiesto di unirti"</string>
|
||||
<string name="state_event_room_knock_denied">"%1$s ha rifiutato la richiesta di unirsi di %2$s"</string>
|
||||
<string name="state_event_room_knock_denied_by_you">"Hai rifiutato la richiesta di unirsi di %1$s"</string>
|
||||
<string name="state_event_room_knock_denied_you">"%1$s ha rifiutato la tua richiesta di unirti"</string>
|
||||
<string name="state_event_room_knock_retracted">"%1$s non è più interessato a partecipare"</string>
|
||||
<string name="state_event_room_knock_retracted_by_you">"Hai annullato la tua richiesta di unirti"</string>
|
||||
<string name="state_event_room_leave">"%1$s ha lasciato la stanza"</string>
|
||||
<string name="state_event_room_leave_by_you">"Hai lasciato la stanza"</string>
|
||||
<string name="state_event_room_name_changed">"%1$s ha cambiato il nome della stanza in: %2$s"</string>
|
||||
<string name="state_event_room_name_changed_by_you">"Hai cambiato il nome della stanza in: %1$s"</string>
|
||||
<string name="state_event_room_name_removed">"%1$s ha rimosso il nome della stanza"</string>
|
||||
<string name="state_event_room_name_removed_by_you">"Hai rimosso il nome della stanza"</string>
|
||||
<string name="state_event_room_reject">"%1$s ha rifiutato l\'invito"</string>
|
||||
<string name="state_event_room_reject_by_you">"Hai rifiutato l\'invito"</string>
|
||||
<string name="state_event_room_remove">"%1$s ha rimosso %2$s"</string>
|
||||
<string name="state_event_room_remove_by_you">"Hai rimosso %1$s"</string>
|
||||
<string name="state_event_room_third_party_invite">"%1$s ha inviato un invito a %2$s per unirsi alla stanza"</string>
|
||||
<string name="state_event_room_third_party_invite_by_you">"Hai inviato un invito a %1$s per unirsi alla stanza"</string>
|
||||
<string name="state_event_room_third_party_revoked_invite">"%1$s ha revocato l\'invito di %2$s ad unirsi alla stanza."</string>
|
||||
<string name="state_event_room_third_party_revoked_invite_by_you">"Hai revocato l\'invito a %1$s a universi alla stanza"</string>
|
||||
<string name="state_event_room_topic_changed">"%1$s ha cambiato l\'oggetto in: %2$s"</string>
|
||||
<string name="state_event_room_topic_changed_by_you">"Hai cambiato l\'oggetto in: %1$s"</string>
|
||||
<string name="state_event_room_topic_removed">"%1$s ha rimosso l\'oggetto della stanza"</string>
|
||||
<string name="state_event_room_topic_removed_by_you">"Hai rimosso l\'oggetto della stanza"</string>
|
||||
<string name="state_event_room_unban">"%1$s ha sbloccato %2$s"</string>
|
||||
<string name="state_event_room_unban_by_you">"Hai sbloccato %1$s"</string>
|
||||
<string name="state_event_room_unknown_membership_change">"%1$s ha apportato una modifica sconosciuta alla propria iscrizione"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_roomlist_a11y_create_message">"Creați o conversație sau o cameră nouă"</string>
|
||||
<string name="screen_roomlist_main_space_title">"Toate conversatiile"</string>
|
||||
<string name="session_verification_banner_message">"Se pare că folosiți un dispozitiv nou. Verificați-vă identitatea pentru acces la mesajele dumneavoastră criptate."</string>
|
||||
<string name="session_verification_banner_title">"Accesați istoricul mesajelor"</string>
|
||||
<string name="state_event_avatar_changed_too">"(s-a schimbat si avatarul)"</string>
|
||||
<string name="state_event_avatar_url_changed">"%1$s și-a schimbat avatarul"</string>
|
||||
<string name="state_event_avatar_url_changed_by_you">"V-ați schimbat avatarul"</string>
|
||||
<string name="state_event_display_name_changed_from">"%1$s și-a schimbat numele din %2$s în %3$s"</string>
|
||||
<string name="state_event_display_name_changed_from_by_you">"V-ați schimbat numele din %1$s în %2$s"</string>
|
||||
<string name="state_event_display_name_removed">"%1$s și-a sters numele (era %2$s)"</string>
|
||||
<string name="state_event_display_name_removed_by_you">"V-ați sters numele (era %1$s)"</string>
|
||||
<string name="state_event_display_name_set">"%1$s și-a schimbat numele %2$s"</string>
|
||||
<string name="state_event_display_name_set_by_you">"V-ați schimbat numele în %1$s"</string>
|
||||
<string name="state_event_room_avatar_changed">"%1$s a schimbat avatarul camerei"</string>
|
||||
<string name="state_event_room_avatar_changed_by_you">"Ați schimbat avatarul camerei"</string>
|
||||
<string name="state_event_room_avatar_removed">"%1$s a șters avatarul camerei"</string>
|
||||
<string name="state_event_room_avatar_removed_by_you">"Ați șters avatarul camerei"</string>
|
||||
<string name="state_event_room_ban">"%1$s a adăugat o interdicție pentru %2$s"</string>
|
||||
<string name="state_event_room_ban_by_you">"Ați adăugat o interdicție pentru %1$s"</string>
|
||||
<string name="state_event_room_created">"%1$s a creat camera"</string>
|
||||
<string name="state_event_room_created_by_you">"Ați creat camera"</string>
|
||||
<string name="state_event_room_invite">"%1$s l-a invitat pe %2$s"</string>
|
||||
<string name="state_event_room_invite_accepted">"%1$s a acceptat invitația"</string>
|
||||
<string name="state_event_room_invite_accepted_by_you">"Ați acceptat invitația"</string>
|
||||
<string name="state_event_room_invite_by_you">"L-ați invitat pe %1$s"</string>
|
||||
<string name="state_event_room_invite_you">"%1$s v-a invitat"</string>
|
||||
<string name="state_event_room_join">"%1$s a intrat în cameră"</string>
|
||||
<string name="state_event_room_join_by_you">"Ați intrat în cameră"</string>
|
||||
<string name="state_event_room_knock">"%1$s a solicitat să se alăture camerei"</string>
|
||||
<string name="state_event_room_knock_accepted">"%1$s i-a permis lui %2$s să se alăture camerei"</string>
|
||||
<string name="state_event_room_knock_accepted_by_you">"%1$s v-a permis să vă alăturați camerei"</string>
|
||||
<string name="state_event_room_knock_by_you">"Ați solicitat să vă alăturați camerei"</string>
|
||||
<string name="state_event_room_knock_denied">"%1$s a respins solicitarea de alăturare a lui %2$s"</string>
|
||||
<string name="state_event_room_knock_denied_by_you">"Ați respins solicitarea de alăturare a lui %1$s"</string>
|
||||
<string name="state_event_room_knock_denied_you">"%1$s a respins cererea dumneavoastră de alăturare"</string>
|
||||
<string name="state_event_room_knock_retracted">"%1$s nu mai este interesat să se alăture camerei"</string>
|
||||
<string name="state_event_room_knock_retracted_by_you">"Ați anulat cererea de alăturare"</string>
|
||||
<string name="state_event_room_leave">"%1$s a părăsit camera"</string>
|
||||
<string name="state_event_room_leave_by_you">"Ați părăsit camera"</string>
|
||||
<string name="state_event_room_name_changed">"%1$s a schimbat numele camerei în: %2$s"</string>
|
||||
<string name="state_event_room_name_changed_by_you">"Ați schimbat numele camerei în: %1$s"</string>
|
||||
<string name="state_event_room_name_removed">"%1$s a sters numele camerei"</string>
|
||||
<string name="state_event_room_name_removed_by_you">"Ați șters numele camerei"</string>
|
||||
<string name="state_event_room_reject">"%1$s a respins invitația"</string>
|
||||
<string name="state_event_room_reject_by_you">"Ați respins invitația"</string>
|
||||
<string name="state_event_room_remove">"%1$s l-a îndepărtat pe %2$s"</string>
|
||||
<string name="state_event_room_remove_by_you">"L-ați îndepărtat pe %1$s"</string>
|
||||
<string name="state_event_room_third_party_invite">"%1$s a trimis o invitație către %2$s pentru a se alătura camerei"</string>
|
||||
<string name="state_event_room_third_party_invite_by_you">"Ați trimis o invitație către %1$s pentru a se alătura camerei"</string>
|
||||
<string name="state_event_room_third_party_revoked_invite">"%1$s a revocat invitația pentru %2$s de a se alătura camerei"</string>
|
||||
<string name="state_event_room_third_party_revoked_invite_by_you">"Ați revocat invitația pentru %1$s de a se alătura camerei"</string>
|
||||
<string name="state_event_room_topic_changed">"%1$s a schimbat subiectul în: %2$s"</string>
|
||||
<string name="state_event_room_topic_changed_by_you">"Ați schimbat subiectul în: %1$s"</string>
|
||||
<string name="state_event_room_topic_removed">"%1$s a șters subiectul camerei"</string>
|
||||
<string name="state_event_room_topic_removed_by_you">"Ați șters subiectul camerei"</string>
|
||||
<string name="state_event_room_unban">"%1$s a anulat interdicția pentru %2$s"</string>
|
||||
<string name="state_event_room_unban_by_you">"Ați anulat interdicția pentru %1$s"</string>
|
||||
<string name="state_event_room_unknown_membership_change">"%1$s a făcut o modificare necunoscută asupra calității sale de membru"</string>
|
||||
</resources>
|
||||
|
|
@ -24,8 +24,8 @@ import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
|||
import io.element.android.libraries.dateformatter.api.LastMessageTimestampFormatter
|
||||
import io.element.android.libraries.dateformatter.test.FakeLastMessageTimestampFormatter
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
|
||||
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
|
|
@ -49,6 +49,7 @@ class RoomListPresenterTests {
|
|||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -75,6 +76,7 @@ class RoomListPresenterTests {
|
|||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -95,6 +97,7 @@ class RoomListPresenterTests {
|
|||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -119,6 +122,7 @@ class RoomListPresenterTests {
|
|||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -148,6 +152,7 @@ class RoomListPresenterTests {
|
|||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -182,6 +187,7 @@ class RoomListPresenterTests {
|
|||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -230,6 +236,7 @@ class RoomListPresenterTests {
|
|||
givenIsReady(true)
|
||||
givenVerifiedStatus(SessionVerifiedStatus.NotVerified)
|
||||
},
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
|
|
@ -242,32 +249,6 @@ class RoomListPresenterTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - presentVerificationSuccessfulMessage & ClearVerificationSuccesfulMessage`() = runTest {
|
||||
val roomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||
val presenter = RoomListPresenter(
|
||||
FakeMatrixClient(
|
||||
sessionId = A_SESSION_ID,
|
||||
roomSummaryDataSource = roomSummaryDataSource
|
||||
),
|
||||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService().apply {
|
||||
givenIsReady(true)
|
||||
givenVerificationFlowState(VerificationFlowState.Finished)
|
||||
},
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
skipItems(1)
|
||||
val displayMessageItem = awaitItem()
|
||||
Truth.assertThat(displayMessageItem.presentVerificationSuccessfulMessage).isTrue()
|
||||
displayMessageItem.eventSink(RoomListEvents.ClearSuccessfulVerificationMessage)
|
||||
Truth.assertThat(awaitItem().presentVerificationSuccessfulMessage).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDateFormatter(): LastMessageTimestampFormatter {
|
||||
return FakeLastMessageTimestampFormatter().apply {
|
||||
givenFormat(A_FORMATTED_DATE)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_session_verification_cancelled_subtitle">"Algo no fue bien. Se agotó el tiempo de espera de la solicitud o se rechazó."</string>
|
||||
<string name="screen_session_verification_cancelled_title">"Verificación cancelada"</string>
|
||||
<string name="screen_session_verification_compare_emojis_subtitle">"Confirma que los emojis que aparecen a continuación coinciden con los que aparecen en tu otra sesión."</string>
|
||||
<string name="screen_session_verification_compare_emojis_title">"Comparar emojis"</string>
|
||||
<string name="screen_session_verification_complete_subtitle">"Tu nueva sesión ya está verificada. Tienes acceso a tus mensajes cifrados y otros usuarios lo considerarán de confianza."</string>
|
||||
<string name="screen_session_verification_open_existing_session_subtitle">"Demuestra que eres tú para acceder a tu historial de mensajes cifrados."</string>
|
||||
<string name="screen_session_verification_open_existing_session_title">"Abrir una sesión existente"</string>
|
||||
<string name="screen_session_verification_positive_button_canceled">"Reintentar la verificación"</string>
|
||||
<string name="screen_session_verification_positive_button_initial">"Estoy listo"</string>
|
||||
<string name="screen_session_verification_positive_button_ready">"Comenzar"</string>
|
||||
<string name="screen_session_verification_positive_button_verifying_ongoing">"Esperando a que coincida"</string>
|
||||
<string name="screen_session_verification_request_accepted_subtitle">"Compara los emoji, asegurándote de que aparecen en el mismo orden."</string>
|
||||
<string name="screen_session_verification_they_dont_match">"No coinciden"</string>
|
||||
<string name="screen_session_verification_they_match">"Coinciden"</string>
|
||||
<string name="screen_session_verification_waiting_to_accept_subtitle">"Acepta la solicitud para iniciar el proceso de verificación en tu otra sesión para continuar."</string>
|
||||
<string name="screen_session_verification_waiting_to_accept_title">"A la espera de aceptar la solicitud"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_session_verification_cancelled_subtitle">"C\'è qualcosa che non va. La richiesta è scaduta o è stata rifiutata."</string>
|
||||
<string name="screen_session_verification_cancelled_title">"Verifica annullata"</string>
|
||||
<string name="screen_session_verification_compare_emojis_subtitle">"Verifica che gli emoji sottostanti corrispondano a quelli mostrati nell\'altra sessione."</string>
|
||||
<string name="screen_session_verification_compare_emojis_title">"Confronta le emoji"</string>
|
||||
<string name="screen_session_verification_complete_subtitle">"La tua nuova sessione è ora verificata. Ha accesso ai tuoi messaggi crittografati e gli altri utenti la vedranno come attendibile."</string>
|
||||
<string name="screen_session_verification_open_existing_session_subtitle">"Dimostra la tua identità per accedere alla cronologia dei messaggi crittografati."</string>
|
||||
<string name="screen_session_verification_open_existing_session_title">"Apri una sessione esistente"</string>
|
||||
<string name="screen_session_verification_positive_button_canceled">"Riprova la verifica"</string>
|
||||
<string name="screen_session_verification_positive_button_initial">"Sono pronto"</string>
|
||||
<string name="screen_session_verification_positive_button_ready">"Inizia"</string>
|
||||
<string name="screen_session_verification_positive_button_verifying_ongoing">"In attesa di un riscontro"</string>
|
||||
<string name="screen_session_verification_request_accepted_subtitle">"Confronta le emoji uniche, assicurandoti che appaiano nello stesso ordine."</string>
|
||||
<string name="screen_session_verification_they_dont_match">"Non corrispondono"</string>
|
||||
<string name="screen_session_verification_they_match">"Corrispondono"</string>
|
||||
<string name="screen_session_verification_waiting_to_accept_subtitle">"Accetta la richiesta di avviare il processo di verifica nell\'altra sessione per continuare."</string>
|
||||
<string name="screen_session_verification_waiting_to_accept_title">"In attesa di accettare la richiesta"</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="screen_session_verification_cancelled_subtitle">"Ceva nu este în regulă. Fie cererea a expirat, fie a fost respinsă."</string>
|
||||
<string name="screen_session_verification_cancelled_title">"Verificare anulată"</string>
|
||||
<string name="screen_session_verification_compare_emojis_subtitle">"Confirmați că emoticoanele de mai jos se potrivesc cu cele afișate în cealaltă sesiune."</string>
|
||||
<string name="screen_session_verification_compare_emojis_title">"Comparați emoticoanele"</string>
|
||||
<string name="screen_session_verification_complete_subtitle">"Noua dumneavoastră sesiune este acum verificată. Are acces la mesajele dumneavoastră criptate, iar alți utilizatori vă vor vedea ca fiind de încredere."</string>
|
||||
<string name="screen_session_verification_open_existing_session_subtitle">"Demonstrați-vă identitatea pentru a accesa istoricul mesajelor criptate."</string>
|
||||
<string name="screen_session_verification_open_existing_session_title">"Deschideți o sesiune existentă"</string>
|
||||
<string name="screen_session_verification_positive_button_canceled">"Reîncercați verificarea"</string>
|
||||
<string name="screen_session_verification_positive_button_initial">"Sunt pregătit"</string>
|
||||
<string name="screen_session_verification_positive_button_ready">"Începeți"</string>
|
||||
<string name="screen_session_verification_positive_button_verifying_ongoing">"Se așteaptă confirmarea"</string>
|
||||
<string name="screen_session_verification_request_accepted_subtitle">"Comparăți emoticoalene asigurându-vă că apar în aceeași ordine."</string>
|
||||
<string name="screen_session_verification_they_dont_match">"Nu se potrivesc"</string>
|
||||
<string name="screen_session_verification_they_match">"Se potrivesc"</string>
|
||||
<string name="screen_session_verification_waiting_to_accept_subtitle">"Acceptați solicitarea de a începe procesul de verificare în cealaltă sesiune pentru a continua."</string>
|
||||
<string name="screen_session_verification_waiting_to_accept_title">"Se așteptă acceptarea cererii"</string>
|
||||
</resources>
|
||||
|
|
@ -27,9 +27,11 @@ import io.element.android.libraries.architecture.Async
|
|||
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationEmoji
|
||||
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
class VerifySelfSessionPresenterTests {
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue