Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: show sync retry state for internal build #WPB-11198 #3505

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,19 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.IntSize
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.wire.android.BuildConfig
import com.wire.android.R
import com.wire.android.ui.theme.ThemeOption
import com.wire.android.ui.theme.WireTheme
Expand All @@ -52,6 +58,7 @@ import com.wire.android.ui.theme.wireDimensions
import com.wire.android.ui.theme.wireTypography
import com.wire.android.util.ui.PreviewMultipleThemes
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.network.NetworkState

@Composable
fun CommonTopAppBar(
Expand All @@ -65,6 +72,7 @@ fun CommonTopAppBar(
Column(modifier = modifier) {
ConnectivityStatusBar(
themeOption = themeOption,
networkState = commonTopAppBarState.networkState,
connectivityInfo = commonTopAppBarState.connectivityState,
onReturnToCallClick = onReturnToCallClick,
onReturnToIncomingCallClick = onReturnToIncomingCallClick,
Expand All @@ -79,7 +87,10 @@ fun getBackgroundColor(connectivityInfo: ConnectivityUIState): Color {
is ConnectivityUIState.EstablishedCall,
is ConnectivityUIState.IncomingCall,
is ConnectivityUIState.OutgoingCall -> MaterialTheme.wireColorScheme.positive
ConnectivityUIState.Connecting, ConnectivityUIState.WaitingConnection -> MaterialTheme.wireColorScheme.primary

is ConnectivityUIState.WaitingConnection,
ConnectivityUIState.Connecting -> MaterialTheme.wireColorScheme.primary

ConnectivityUIState.None -> MaterialTheme.wireColorScheme.background
}
}
Expand All @@ -88,6 +99,7 @@ fun getBackgroundColor(connectivityInfo: ConnectivityUIState): Color {
private fun ConnectivityStatusBar(
themeOption: ThemeOption,
connectivityInfo: ConnectivityUIState,
networkState: NetworkState,
onReturnToCallClick: (ConnectivityUIState.EstablishedCall) -> Unit,
onReturnToIncomingCallClick: (ConnectivityUIState.IncomingCall) -> Unit,
onReturnToOutgoingCallClick: (ConnectivityUIState.OutgoingCall) -> Unit
Expand Down Expand Up @@ -119,14 +131,23 @@ private fun ConnectivityStatusBar(
.background(backgroundColor)
.run {
when (connectivityInfo) {
is ConnectivityUIState.EstablishedCall ->
clickable(onClick = { onReturnToCallClick(connectivityInfo) })
is ConnectivityUIState.EstablishedCall -> clickable(onClick = {
onReturnToCallClick(
connectivityInfo
)
})

is ConnectivityUIState.IncomingCall ->
clickable(onClick = { onReturnToIncomingCallClick(connectivityInfo) })
is ConnectivityUIState.IncomingCall -> clickable(onClick = {
onReturnToIncomingCallClick(
connectivityInfo
)
})

is ConnectivityUIState.OutgoingCall ->
clickable(onClick = { onReturnToOutgoingCallClick(connectivityInfo) })
is ConnectivityUIState.OutgoingCall -> clickable(onClick = {
onReturnToOutgoingCallClick(
connectivityInfo
)
})

else -> this
}
Expand Down Expand Up @@ -158,18 +179,63 @@ private fun ConnectivityStatusBar(
MaterialTheme.wireColorScheme.onPrimary
)

ConnectivityUIState.WaitingConnection ->
StatusLabel(
R.string.connectivity_status_bar_waiting_for_network,
MaterialTheme.wireColorScheme.onPrimary
)
is ConnectivityUIState.WaitingConnection -> {
val color = MaterialTheme.wireColorScheme.onPrimary
val waitingStatus: @Composable () -> Unit = {
StatusLabel(
stringResource = R.string.connectivity_status_bar_waiting_for_network,
color
)
}

if (!BuildConfig.PRIVATE_BUILD) {
waitingStatus()
return@Column
}

WaitingStatusLabelInternal(connectivityInfo, networkState, waitingStatus)
}

ConnectivityUIState.None -> {}
}
}
}
}

@Composable
private fun WaitingStatusLabelInternal(
connectivityInfo: ConnectivityUIState.WaitingConnection,
networkState: NetworkState,
waitingStatus: @Composable () -> Unit,
) {
assert(BuildConfig.PRIVATE_BUILD) { "This composable should only be used in the internal versions" }

val cause = connectivityInfo.cause?.javaClass?.simpleName ?: "null"
val delay = connectivityInfo.retryDelay ?: "null"
var fontSize by remember { mutableStateOf(1f) }

Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
waitingStatus()
Text(
text = "Cause: $cause Delay: $delay, Net: $networkState",
style = MaterialTheme.wireTypography.title03.copy(
fontSize = MaterialTheme.wireTypography.title03.fontSize * fontSize,
color = MaterialTheme.wireColorScheme.onPrimary,
),
onTextLayout = {
// This is used to make sure the text fits in the available space
// so no needed information is cut off. It introduces a small delay in the text
// rendering but it is not important as this code is only used in the debug version
if (it.hasVisualOverflow) {
fontSize *= 0.9f
}
},
)
}
}

@Composable
private fun OngoingCallContent(isMuted: Boolean) {
Row {
Expand Down Expand Up @@ -208,11 +274,23 @@ private fun OutgoingCallContent(conversationName: String?) {
private fun StatusLabel(
stringResource: Int,
color: Color = MaterialTheme.wireColorScheme.onPrimary
) {
StatusLabel(
string = stringResource(id = stringResource),
color = color,
)
}

@Composable
private fun StatusLabel(
string: String,
color: Color = MaterialTheme.wireColorScheme.onPrimary
) {
Text(
text = stringResource(id = stringResource).uppercase(),
text = string.uppercase(),
color = color,
style = MaterialTheme.wireTypography.title03,
textAlign = TextAlign.Center,
)
}

Expand Down Expand Up @@ -294,7 +372,32 @@ fun PreviewCommonTopAppBar_ConnectivityCallNotMuted() =
fun PreviewCommonTopAppBar_ConnectivityConnecting() =
PreviewCommonTopAppBar(ConnectivityUIState.Connecting)

@PreviewMultipleThemes
@Composable
fun PreviewCommonTopAppBar_ConnectivityWaitingConnection() =
PreviewCommonTopAppBar(ConnectivityUIState.WaitingConnection(null, null))

@PreviewMultipleThemes
@Composable
fun PreviewCommonTopAppBar_ConnectivityNone() =
PreviewCommonTopAppBar(ConnectivityUIState.None)

@PreviewMultipleThemes
@Composable
fun PreviewCommonTopAppBar_ConnectivityIncomingCall() =
PreviewCommonTopAppBar(
ConnectivityUIState.IncomingCall(
ConversationId("what", "ever"),
"callerName"
)
)

@PreviewMultipleThemes
@Composable
fun PreviewCommonTopAppBar_ConnectivityOutgoingCall() =
PreviewCommonTopAppBar(
ConnectivityUIState.OutgoingCall(
ConversationId("what", "ever"),
"conversationName"
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
*/
package com.wire.android.ui.common.topappbar

import com.wire.kalium.network.NetworkState

data class CommonTopAppBarState(
val connectivityState: ConnectivityUIState = ConnectivityUIState.None,
val networkState: NetworkState = NetworkState.NotConnected,
)
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ class CommonTopAppBarViewModel @Inject constructor(
coreLogic.sessionScope(userId) {
observeSyncState().map {
when (it) {
is SyncState.Failed, SyncState.Waiting -> Connectivity.WAITING_CONNECTION
SyncState.GatheringPendingEvents, SyncState.SlowSync -> Connectivity.CONNECTING
SyncState.Live -> Connectivity.CONNECTED
SyncState.Waiting -> Connectivity.WaitingConnection(null, null)
is SyncState.Failed -> Connectivity.WaitingConnection(it.cause, it.retryDelay)
SyncState.GatheringPendingEvents, SyncState.SlowSync -> Connectivity.Connecting
SyncState.Live -> Connectivity.Connected
}
}
}
Expand Down Expand Up @@ -117,6 +118,9 @@ class CommonTopAppBarViewModel @Inject constructor(
state = state.copy(connectivityState = connectivityUIState)
}
}
coreLogic.networkStateObserver.observeNetworkState().collectLatest {
state = state.copy(networkState = it)
}
}
}

Expand All @@ -129,20 +133,38 @@ class CommonTopAppBarViewModel @Inject constructor(
val canDisplayConnectivityIssues = currentScreen !is CurrentScreen.AuthRelated

if (activeCall != null) {
return if (activeCall.status == CallStatus.INCOMING) {
ConnectivityUIState.IncomingCall(activeCall.conversationId, activeCall.callerName)
} else if (activeCall.status == CallStatus.STARTED) {
ConnectivityUIState.OutgoingCall(activeCall.conversationId, activeCall.conversationName)
} else {
ConnectivityUIState.EstablishedCall(activeCall.conversationId, activeCall.isMuted)
return when (activeCall.status) {
CallStatus.INCOMING -> {
ConnectivityUIState.IncomingCall(
activeCall.conversationId,
activeCall.callerName
)
}

CallStatus.STARTED -> {
ConnectivityUIState.OutgoingCall(
activeCall.conversationId,
activeCall.conversationName
)
}

else -> {
ConnectivityUIState.EstablishedCall(
activeCall.conversationId,
activeCall.isMuted
)
}
}
}

return if (canDisplayConnectivityIssues) {
when (connectivity) {
Connectivity.WAITING_CONNECTION -> ConnectivityUIState.WaitingConnection
Connectivity.CONNECTING -> ConnectivityUIState.Connecting
Connectivity.CONNECTED -> ConnectivityUIState.None
Connectivity.Connecting -> ConnectivityUIState.Connecting
Connectivity.Connected -> ConnectivityUIState.None
is Connectivity.WaitingConnection -> ConnectivityUIState.WaitingConnection(
connectivity.cause,
connectivity.retryDelay,
)
}
} else {
ConnectivityUIState.None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

package com.wire.android.ui.common.topappbar

enum class Connectivity {
WAITING_CONNECTION, CONNECTING, CONNECTED
import com.wire.kalium.logic.CoreFailure
import kotlin.time.Duration

sealed interface Connectivity {
data class WaitingConnection(val cause: CoreFailure?, val retryDelay: Duration?) : Connectivity
data object Connecting : Connectivity
data object Connected : Connectivity
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
package com.wire.android.ui.common.topappbar

import androidx.compose.runtime.Stable
import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.data.id.ConversationId
import kotlin.time.Duration

@Stable
sealed interface ConnectivityUIState {
data object Connecting : ConnectivityUIState

data object WaitingConnection : ConnectivityUIState
data class WaitingConnection(val cause: CoreFailure?, val retryDelay: Duration?) : ConnectivityUIState

data object None : ConnectivityUIState

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import com.wire.kalium.logic.feature.call.usecase.ObserveEstablishedCallsUseCase
import com.wire.kalium.logic.feature.call.usecase.ObserveOutgoingCallUseCase
import com.wire.kalium.logic.feature.session.CurrentSessionResult
import com.wire.kalium.logic.sync.ObserveSyncStateUseCase
import com.wire.kalium.network.NetworkState
import com.wire.kalium.network.NetworkStateObserver
import io.mockk.MockKAnnotations
import io.mockk.coEvery
import io.mockk.every
Expand Down Expand Up @@ -264,6 +266,9 @@ class CommonTopAppBarViewModelTest {
@MockK
private lateinit var globalKaliumScope: GlobalKaliumScope

@MockK
private lateinit var networkStateObserver: NetworkStateObserver

init {
MockKAnnotations.init(this)
every {
Expand Down Expand Up @@ -294,6 +299,14 @@ class CommonTopAppBarViewModelTest {
coreLogic.getGlobalScope()
} returns globalKaliumScope

every {
coreLogic.networkStateObserver
} returns networkStateObserver

every {
networkStateObserver.observeNetworkState()
} returns MutableStateFlow(NetworkState.ConnectedWithInternet)

every {
globalKaliumScope.session.currentSessionFlow()
} returns emptyFlow()
Expand Down
Loading