mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 06:55:41 +00:00
[Room List] Show offline indicator when the device is offline (#239)
* Implement the network status indicator. * Add `networkmonitor` feature.
This commit is contained in:
committed by
GitHub
parent
200763e15a
commit
d391275420
@@ -48,6 +48,7 @@ dependencies {
|
||||
implementation(projects.libraries.testtags)
|
||||
implementation(projects.libraries.uiStrings)
|
||||
implementation(projects.libraries.dateformatter.api)
|
||||
implementation(projects.features.networkmonitor.api)
|
||||
implementation(libs.accompanist.placeholder)
|
||||
api(projects.features.roomlist.api)
|
||||
ksp(libs.showkase.processor)
|
||||
@@ -60,6 +61,7 @@ dependencies {
|
||||
testImplementation(libs.test.robolectric)
|
||||
testImplementation(projects.libraries.matrix.test)
|
||||
testImplementation(projects.libraries.dateformatter.test)
|
||||
testImplementation(projects.features.networkmonitor.test)
|
||||
testImplementation(projects.libraries.permissions.noop)
|
||||
|
||||
androidTestImplementation(libs.test.junitext)
|
||||
|
||||
+6
@@ -26,6 +26,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryPlaceholders
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
@@ -42,6 +43,7 @@ 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.ui.model.MatrixUser
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -57,6 +59,7 @@ class RoomListPresenter @Inject constructor(
|
||||
private val lastMessageTimestampFormatter: LastMessageTimestampFormatter,
|
||||
private val roomLastMessageFormatter: RoomLastMessageFormatter,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
private val networkMonitor: NetworkMonitor,
|
||||
private val snackbarDispatcher: SnackbarDispatcher,
|
||||
) : Presenter<RoomListState> {
|
||||
|
||||
@@ -71,6 +74,8 @@ class RoomListPresenter @Inject constructor(
|
||||
.roomSummaries()
|
||||
.collectAsState()
|
||||
|
||||
val networkConnectionStatus by networkMonitor.connectivity.collectAsState(initial = networkMonitor.currentConnectivityStatus)
|
||||
|
||||
Timber.v("RoomSummaries size = ${roomSummaries.size}")
|
||||
|
||||
val filteredRoomSummaries: MutableState<ImmutableList<RoomListRoomSummary>> = remember {
|
||||
@@ -108,6 +113,7 @@ class RoomListPresenter @Inject constructor(
|
||||
filter = filter,
|
||||
displayVerificationPrompt = displayVerificationPrompt,
|
||||
snackbarMessage = snackbarMessage,
|
||||
hasNetworkConnection = networkConnectionStatus == NetworkStatus.Online,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
}
|
||||
|
||||
+1
@@ -28,6 +28,7 @@ data class RoomListState(
|
||||
val roomList: ImmutableList<RoomListRoomSummary>,
|
||||
val filter: String,
|
||||
val displayVerificationPrompt: Boolean,
|
||||
val hasNetworkConnection: Boolean,
|
||||
val snackbarMessage: SnackbarMessage?,
|
||||
val eventSink: (RoomListEvents) -> Unit
|
||||
)
|
||||
|
||||
+2
@@ -33,6 +33,7 @@ open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
|
||||
aRoomListState(),
|
||||
aRoomListState().copy(displayVerificationPrompt = true),
|
||||
aRoomListState().copy(snackbarMessage = SnackbarMessage(StringR.string.common_verification_complete)),
|
||||
aRoomListState().copy(hasNetworkConnection = false),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -40,6 +41,7 @@ internal fun aRoomListState() = RoomListState(
|
||||
matrixUser = MatrixUser(id = UserId("@id"), username = "User#1", avatarData = AvatarData("@id", "U")),
|
||||
roomList = aRoomListRoomSummaryList(),
|
||||
filter = "filter",
|
||||
hasNetworkConnection = true,
|
||||
snackbarMessage = null,
|
||||
displayVerificationPrompt = false,
|
||||
eventSink = {}
|
||||
|
||||
+11
-8
@@ -68,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 io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorView
|
||||
import kotlinx.coroutines.launch
|
||||
import io.element.android.libraries.designsystem.R as DrawableR
|
||||
import io.element.android.libraries.ui.strings.R as StringR
|
||||
@@ -150,14 +151,16 @@ fun RoomListContent(
|
||||
Scaffold(
|
||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
RoomListTopBar(
|
||||
matrixUser = state.matrixUser,
|
||||
filter = state.filter,
|
||||
onFilterChanged = { state.eventSink(RoomListEvents.UpdateFilter(it)) },
|
||||
onOpenSettings = onOpenSettings,
|
||||
scrollBehavior = scrollBehavior,
|
||||
modifier = Modifier,
|
||||
)
|
||||
Column {
|
||||
ConnectivityIndicatorView(isOnline = state.hasNetworkConnection)
|
||||
RoomListTopBar(
|
||||
matrixUser = state.matrixUser,
|
||||
filter = state.filter,
|
||||
onFilterChanged = { state.eventSink(RoomListEvents.UpdateFilter(it)) },
|
||||
onOpenSettings = onOpenSettings,
|
||||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
}
|
||||
},
|
||||
content = { padding ->
|
||||
Column(
|
||||
|
||||
+4
@@ -19,6 +19,7 @@
|
||||
package io.element.android.features.roomlist.impl.components
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.icons.Icons
|
||||
@@ -46,6 +47,7 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import io.element.android.features.roomlist.impl.R
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
@@ -172,6 +174,7 @@ fun SearchRoomListTopBar(
|
||||
)
|
||||
}
|
||||
},
|
||||
windowInsets = WindowInsets(0.dp)
|
||||
)
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
@@ -231,6 +234,7 @@ private fun DefaultRoomListTopBar(
|
||||
}
|
||||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
windowInsets = WindowInsets(0.dp),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -20,6 +20,7 @@ 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.networkmonitor.test.FakeNetworkMonitor
|
||||
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
|
||||
@@ -49,6 +50,7 @@ class RoomListPresenterTests {
|
||||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
FakeNetworkMonitor(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
@@ -76,6 +78,7 @@ class RoomListPresenterTests {
|
||||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
FakeNetworkMonitor(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
@@ -97,6 +100,7 @@ class RoomListPresenterTests {
|
||||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
FakeNetworkMonitor(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
@@ -122,6 +126,7 @@ class RoomListPresenterTests {
|
||||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
FakeNetworkMonitor(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
@@ -152,6 +157,7 @@ class RoomListPresenterTests {
|
||||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
FakeNetworkMonitor(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
@@ -187,6 +193,7 @@ class RoomListPresenterTests {
|
||||
createDateFormatter(),
|
||||
FakeRoomLastMessageFormatter(),
|
||||
FakeSessionVerificationService(),
|
||||
FakeNetworkMonitor(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
@@ -236,6 +243,7 @@ class RoomListPresenterTests {
|
||||
givenIsReady(true)
|
||||
givenVerifiedStatus(SessionVerifiedStatus.NotVerified)
|
||||
},
|
||||
FakeNetworkMonitor(),
|
||||
SnackbarDispatcher(),
|
||||
)
|
||||
moleculeFlow(RecompositionClock.Immediate) {
|
||||
|
||||
Reference in New Issue
Block a user