Skip to content

Commit

Permalink
Move main screen content to be a lazy column
Browse files Browse the repository at this point in the history
  • Loading branch information
jsoberg committed Jan 17, 2024
1 parent 4d98d52 commit 2fa7106
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 128 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package com.soberg.netinfo.android.ui.screen

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.soberg.netinfo.android.ui.screen.state.NetworkInfoViewState
import com.soberg.netinfo.android.ui.screen.state.toDrawableResId
import com.soberg.netinfo.android.ui.screen.state.toTextStringResId
import com.soberg.netinfo.feature.resources.drawables.R as DrawablesR
import com.soberg.netinfo.feature.resources.strings.R as StringsR

@Composable
internal fun NetworkInfoList(
state: NetworkInfoViewState.Ready,
onCopyLanIpClicked: () -> Unit,
onCopyWanIpClicked: () -> Unit,
onLocationClicked: () -> Unit,
modifier: Modifier = Modifier,
) {
LazyColumn(
modifier = modifier.fillMaxSize(),
) {
when (val lanState = state.lan) {
is NetworkInfoViewState.Ready.Lan.Connected -> {
connectedLanListItems(
state = lanState,
onCopyLanIpClicked = onCopyLanIpClicked,
)

wanListItems(
state = state.wan,
onCopyWanIpClicked = onCopyWanIpClicked,
onLocationClicked = onLocationClicked,
)
}

is NetworkInfoViewState.Ready.Lan.Unknown -> {
// TODO: Show error/unknown state
}
}
}
}

private fun LazyListScope.connectedLanListItems(
state: NetworkInfoViewState.Ready.Lan.Connected,
onCopyLanIpClicked: () -> Unit,
) {
item {
NetworkListItem(
titleText = stringResource(StringsR.string.connection_type_content_header),
contentText = stringResource(state.type.toTextStringResId()),
iconDrawableRes = state.type.toDrawableResId(),
)
}

val connectedToVpnContentTextRes = if (state.isConnectedToVpn) {
StringsR.string.vpn_connection_active
} else {
StringsR.string.vpn_connection_inactive
}

val connectedToVpnIconRes = if (state.isConnectedToVpn) {
DrawablesR.drawable.ic_vpn_lock
} else {
DrawablesR.drawable.ic_lock_open
}

item {
NetworkListItem(
titleText = stringResource(StringsR.string.connected_to_vpn_content_header),
contentText = stringResource(id = connectedToVpnContentTextRes),
iconDrawableRes = connectedToVpnIconRes,
)
}

item {
NetworkListItem(
modifier = Modifier
.clickable(onClick = onCopyLanIpClicked),
titleText = stringResource(StringsR.string.local_ip_content_header),
contentText = state.ipAddress,
iconDrawableRes = com.soberg.netinfo.feature.resources.drawables.R.drawable.ic_content_copy,
)
}
}

private fun LazyListScope.wanListItems(
state: NetworkInfoViewState.Ready.Wan,
onCopyWanIpClicked: () -> Unit,
onLocationClicked: () -> Unit,
) {
when (state) {
is NetworkInfoViewState.Ready.Wan.Connected -> {
connectedWanListItems(
state = state,
onCopyWanIpClicked = onCopyWanIpClicked,
onLocationClicked = onLocationClicked,
)
}

is NetworkInfoViewState.Ready.Wan.CannotConnect
-> {
// TODO: Show can't connect content
}
}
}

private fun LazyListScope.connectedWanListItems(
state: NetworkInfoViewState.Ready.Wan.Connected,
onCopyWanIpClicked: () -> Unit,
onLocationClicked: () -> Unit,
) {
item {
NetworkListItem(
modifier = Modifier
.clickable(onClick = onCopyWanIpClicked),
titleText = stringResource(StringsR.string.external_ip_content_header),
contentText = state.ipAddress,
iconDrawableRes = DrawablesR.drawable.ic_content_copy,
)
}

state.locationText?.let { locationText ->
item {
NetworkListItem(
modifier = Modifier
.clickable(onClick = onLocationClicked),
titleText = stringResource(StringsR.string.ip_geolocation_content_header),
contentText = locationText,
iconDrawableRes = DrawablesR.drawable.ic_my_location,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
package com.soberg.netinfo.android.ui.screen

import android.content.Context
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.soberg.netinfo.android.infra.compose.ext.event.CollectComposableEventFlow
import com.soberg.netinfo.android.ui.core.preview.A11yPreview
import com.soberg.netinfo.android.ui.core.preview.ThemedPreview
import com.soberg.netinfo.android.ui.screen.NetworkInfoViewModel.Event
import com.soberg.netinfo.android.ui.screen.loading.NetworkInfoLoading
import com.soberg.netinfo.android.ui.screen.state.NetworkInfoViewState
import com.soberg.netinfo.android.ui.screen.state.toDrawableResId
import com.soberg.netinfo.android.ui.screen.state.toTextStringResId
import com.soberg.netinfo.feature.resources.drawables.R as DrawablesR
import com.soberg.netinfo.feature.resources.strings.R as StringsR

@Composable
fun NetworkInfoScreen(
Expand Down Expand Up @@ -73,7 +66,7 @@ private fun NetworkInfoScreen(
}

is NetworkInfoViewState.Ready -> {
ReadyContent(
NetworkInfoList(
state = state,
onCopyLanIpClicked = onCopyLanIpClicked,
onCopyWanIpClicked = onCopyWanIpClicked,
Expand All @@ -83,123 +76,6 @@ private fun NetworkInfoScreen(
}
}

@Composable
private fun ReadyContent(
state: NetworkInfoViewState.Ready,
onCopyLanIpClicked: () -> Unit,
onCopyWanIpClicked: () -> Unit,
onLocationClicked: () -> Unit,
) {
Column(
modifier = Modifier.fillMaxSize(),
) {

when (state.lan) {
is NetworkInfoViewState.Ready.Lan.Connected -> {
LanReadyContent(
state = state.lan,
onCopyLanIpClicked = onCopyLanIpClicked,
)

WanContent(
state = state.wan,
onCopyWanIpClicked = onCopyWanIpClicked,
onLocationClicked = onLocationClicked,
)
}

is NetworkInfoViewState.Ready.Lan.Unknown -> {
// TODO: Show error/unknown state
}
}
}
}

@Composable
private fun LanReadyContent(
state: NetworkInfoViewState.Ready.Lan.Connected,
onCopyLanIpClicked: () -> Unit,
) {
NetworkListItem(
titleText = stringResource(StringsR.string.connection_type_content_header),
contentText = stringResource(state.type.toTextStringResId()),
iconDrawableRes = state.type.toDrawableResId(),
)

val connectedToVpnContentTextRes = if (state.isConnectedToVpn) {
StringsR.string.vpn_connection_active
} else {
StringsR.string.vpn_connection_inactive
}

val connectedToVpnIconRes = if (state.isConnectedToVpn) {
DrawablesR.drawable.ic_vpn_lock
} else {
DrawablesR.drawable.ic_lock_open
}

NetworkListItem(
titleText = stringResource(StringsR.string.connected_to_vpn_content_header),
contentText = stringResource(id = connectedToVpnContentTextRes),
iconDrawableRes = connectedToVpnIconRes,
)

NetworkListItem(
modifier = Modifier
.clickable(onClick = onCopyLanIpClicked),
titleText = stringResource(StringsR.string.local_ip_content_header),
contentText = state.ipAddress,
iconDrawableRes = DrawablesR.drawable.ic_content_copy,
)
}

@Composable
internal fun WanContent(
state: NetworkInfoViewState.Ready.Wan,
onCopyWanIpClicked: () -> Unit,
onLocationClicked: () -> Unit,
) {
when (state) {
is NetworkInfoViewState.Ready.Wan.Connected -> {
WanReadyContent(
state = state,
onCopyWanIpClicked = onCopyWanIpClicked,
onLocationClicked = onLocationClicked,
)
}

is NetworkInfoViewState.Ready.Wan.CannotConnect
-> {
// TODO: Show can't connect content
}
}
}

@Composable
private fun WanReadyContent(
state: NetworkInfoViewState.Ready.Wan.Connected,
onCopyWanIpClicked: () -> Unit,
onLocationClicked: () -> Unit,
) {
NetworkListItem(
modifier = Modifier
.clickable(onClick = onCopyWanIpClicked),
titleText = stringResource(StringsR.string.external_ip_content_header),
contentText = state.ipAddress,
iconDrawableRes = DrawablesR.drawable.ic_content_copy,
)

state.locationText?.let { locationText ->
NetworkListItem(
modifier = Modifier
.clickable(onClick = onLocationClicked),
titleText = stringResource(StringsR.string.ip_geolocation_content_header),
contentText = locationText,
iconDrawableRes = DrawablesR.drawable.ic_my_location,
)
}
}

@A11yPreview
@Composable
private fun NetworkInfoScreenPreview() = ThemedPreview {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ class NetworkInfoViewModel @Inject internal constructor(
private fun toLanState(
netInterface: NetworkInterface,
): NetworkInfoViewState.Ready.Lan =
when (netInterface.ipAddress) {
when (val ip = netInterface.ipAddress) {
null -> NetworkInfoViewState.Ready.Lan.Unknown
else -> NetworkInfoViewState.Ready.Lan.Connected(
ipAddress = netInterface.ipAddress!!.value,
ipAddress = ip.value,
type = netInterface.type.toViewState(),
isConnectedToVpn = netInterface.isConnectedToVpn,
)
Expand All @@ -78,7 +78,7 @@ class NetworkInfoViewModel @Inject internal constructor(
is WanInfoRepository.Result.Success -> {
dataCache.updateWan(wanResult.wanInfo)
NetworkInfoViewState.Ready.Wan.Connected(
ipAddress = wanResult.wanInfo.ip.toString(),
ipAddress = wanResult.wanInfo.ip.value,
locationText = wanResult.wanInfo.ispGeoInfo?.locationDisplayText(),
)
}
Expand Down

0 comments on commit 2fa7106

Please sign in to comment.