diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-09-07 13:49:22 +0200 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-09-07 13:49:22 +0200 |
| commit | 827a84c9287705e30487f2f53b360e05dc418f54 (patch) | |
| tree | 8861ee6dfc6499ba76a0b993ab6de7a8620b25c5 /android/app/src | |
| parent | aec8962f16c7d0bdb6b6af4d5e6577aed2b4a575 (diff) | |
| parent | ed29c932534155ad1de9d27c6d91a0184f635497 (diff) | |
| download | mullvadvpn-827a84c9287705e30487f2f53b360e05dc418f54.tar.xz mullvadvpn-827a84c9287705e30487f2f53b360e05dc418f54.zip | |
Merge branch 'migrate-headerbar-to-compose-droid-192'
Diffstat (limited to 'android/app/src')
4 files changed, 142 insertions, 154 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt index 2cfe0c65d9..b04c23d817 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt @@ -37,8 +37,10 @@ fun ScaffoldWithTopBar( content: @Composable (PaddingValues) -> Unit, ) { val systemUiController = rememberSystemUiController() - systemUiController.setStatusBarColor(statusBarColor) - systemUiController.setNavigationBarColor(navigationBarColor) + LaunchedEffect(key1 = statusBarColor, key2 = navigationBarColor) { + systemUiController.setStatusBarColor(statusBarColor) + systemUiController.setNavigationBarColor(navigationBarColor) + } Scaffold( topBar = { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt index ac9ea5cf1c..d250a5467e 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt @@ -35,6 +35,7 @@ import net.mullvad.mullvadvpn.compose.button.SwitchLocationButton import net.mullvad.mullvadvpn.compose.component.ConnectionStatusText import net.mullvad.mullvadvpn.compose.component.LocationInfo import net.mullvad.mullvadvpn.compose.component.Notification +import net.mullvad.mullvadvpn.compose.component.ScaffoldWithTopBar import net.mullvad.mullvadvpn.compose.state.ConnectUiState import net.mullvad.mullvadvpn.compose.test.CIRCULAR_PROGRESS_INDICATOR import net.mullvad.mullvadvpn.compose.test.CONNECT_BUTTON_TEST_TAG @@ -43,6 +44,7 @@ import net.mullvad.mullvadvpn.compose.test.RECONNECT_BUTTON_TEST_TAG import net.mullvad.mullvadvpn.compose.test.SCROLLABLE_COLUMN_TEST_TAG import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_BUTTON_TEST_TAG import net.mullvad.mullvadvpn.lib.common.util.openAccountPageInBrowser +import net.mullvad.mullvadvpn.lib.theme.AlphaTopBar import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.lib.theme.Dimens import net.mullvad.mullvadvpn.model.TunnelState @@ -75,7 +77,9 @@ fun ConnectScreen( onToggleTunnelInfo: () -> Unit = {}, onUpdateVersionClick: () -> Unit = {}, onManageAccountClick: () -> Unit = {}, - onOpenOutOfTimeScreen: () -> Unit = {} + onOpenOutOfTimeScreen: () -> Unit = {}, + onSettingsClick: () -> Unit = {}, + onAccountClick: () -> Unit = {} ) { val context = LocalContext.current LaunchedEffect(key1 = Unit) { @@ -102,104 +106,130 @@ fun ConnectScreen( } } - Column( - verticalArrangement = Arrangement.Bottom, - horizontalAlignment = Alignment.Start, - modifier = - Modifier.background(color = MaterialTheme.colorScheme.primary) - .fillMaxHeight() - .verticalScroll(scrollState) - .padding(bottom = Dimens.screenVerticalMargin) - .testTag(SCROLLABLE_COLUMN_TEST_TAG) + ScaffoldWithTopBar( + topBarColor = + if (uiState.tunnelUiState.isSecured()) { + MaterialTheme.colorScheme.inversePrimary + } else { + MaterialTheme.colorScheme.error + }, + statusBarColor = + if (uiState.tunnelUiState.isSecured()) { + MaterialTheme.colorScheme.inversePrimary + } else { + MaterialTheme.colorScheme.error + }, + navigationBarColor = MaterialTheme.colorScheme.primary, + iconTintColor = + if (uiState.tunnelUiState.isSecured()) { + MaterialTheme.colorScheme.onPrimary + } else { + MaterialTheme.colorScheme.onError + } + .copy(alpha = AlphaTopBar), + onSettingsClicked = onSettingsClick, + onAccountClicked = onAccountClick ) { - Notification( - connectNotificationState = uiState.connectNotificationState, - onClickUpdateVersion = onUpdateVersionClick, - onClickShowAccount = onManageAccountClick - ) - Spacer(modifier = Modifier.weight(1f)) - if ( - uiState.tunnelRealState is TunnelState.Connecting || - (uiState.tunnelRealState is TunnelState.Disconnecting && - uiState.tunnelRealState.actionAfterDisconnect == - ActionAfterDisconnect.Reconnect) + Column( + verticalArrangement = Arrangement.Bottom, + horizontalAlignment = Alignment.Start, + modifier = + Modifier.padding(it) + .background(color = MaterialTheme.colorScheme.primary) + .fillMaxHeight() + .verticalScroll(scrollState) + .padding(bottom = Dimens.screenVerticalMargin) + .testTag(SCROLLABLE_COLUMN_TEST_TAG) ) { - CircularProgressIndicator( + Notification( + connectNotificationState = uiState.connectNotificationState, + onClickUpdateVersion = onUpdateVersionClick, + onClickShowAccount = onManageAccountClick + ) + Spacer(modifier = Modifier.weight(1f)) + if ( + uiState.tunnelRealState is TunnelState.Connecting || + (uiState.tunnelRealState is TunnelState.Disconnecting && + uiState.tunnelRealState.actionAfterDisconnect == + ActionAfterDisconnect.Reconnect) + ) { + CircularProgressIndicator( + color = MaterialTheme.colorScheme.onPrimary, + modifier = + Modifier.padding( + start = Dimens.sideMargin, + end = Dimens.sideMargin, + top = Dimens.mediumPadding + ) + .size( + width = Dimens.progressIndicatorSize, + height = Dimens.progressIndicatorSize + ) + .align(Alignment.CenterHorizontally) + .testTag(CIRCULAR_PROGRESS_INDICATOR) + ) + } + Spacer(modifier = Modifier.height(Dimens.mediumPadding)) + ConnectionStatusText( + state = uiState.tunnelRealState, + modifier = Modifier.padding(horizontal = Dimens.sideMargin) + ) + Text( + text = uiState.location?.country ?: "", + style = MaterialTheme.typography.headlineLarge, color = MaterialTheme.colorScheme.onPrimary, + modifier = Modifier.padding(horizontal = Dimens.sideMargin) + ) + Text( + text = uiState.location?.city ?: "", + style = MaterialTheme.typography.headlineLarge, + color = MaterialTheme.colorScheme.onPrimary, + modifier = Modifier.padding(horizontal = Dimens.sideMargin) + ) + LocationInfo( + onToggleTunnelInfo = onToggleTunnelInfo, + isVisible = + uiState.tunnelRealState != TunnelState.Disconnected && + uiState.location?.hostname != null, + isExpanded = uiState.isTunnelInfoExpanded, + location = uiState.location, + inAddress = uiState.inAddress, + outAddress = uiState.outAddress, modifier = - Modifier.padding( - start = Dimens.sideMargin, - end = Dimens.sideMargin, - top = Dimens.mediumPadding - ) - .size( - width = Dimens.progressIndicatorSize, - height = Dimens.progressIndicatorSize - ) - .align(Alignment.CenterHorizontally) - .testTag(CIRCULAR_PROGRESS_INDICATOR) + Modifier.fillMaxWidth() + .padding(horizontal = Dimens.sideMargin) + .testTag(LOCATION_INFO_TEST_TAG) + ) + Spacer(modifier = Modifier.height(Dimens.buttonSeparation)) + SwitchLocationButton( + modifier = + Modifier.fillMaxWidth() + .height(Dimens.selectLocationButtonHeight) + .padding(horizontal = Dimens.sideMargin) + .testTag(SELECT_LOCATION_BUTTON_TEST_TAG), + onClick = onSwitchLocationClick, + showChevron = uiState.showLocation, + text = + if (uiState.showLocation) { + uiState.relayLocation?.locationName ?: "" + } else { + stringResource(id = R.string.switch_location) + } + ) + Spacer(modifier = Modifier.height(Dimens.buttonSeparation)) + ConnectionButton( + state = uiState.tunnelUiState, + modifier = + Modifier.fillMaxWidth() + .height(Dimens.connectButtonHeight) + .padding(horizontal = Dimens.sideMargin) + .testTag(CONNECT_BUTTON_TEST_TAG), + disconnectClick = onDisconnectClick, + reconnectClick = { handleThrottledAction(onReconnectClick) }, + cancelClick = onCancelClick, + connectClick = { handleThrottledAction(onConnectClick) }, + reconnectButtonTestTag = RECONNECT_BUTTON_TEST_TAG ) } - Spacer(modifier = Modifier.height(Dimens.mediumPadding)) - ConnectionStatusText( - state = uiState.tunnelRealState, - modifier = Modifier.padding(horizontal = Dimens.sideMargin) - ) - Text( - text = uiState.location?.country ?: "", - style = MaterialTheme.typography.headlineLarge, - color = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.padding(horizontal = Dimens.sideMargin) - ) - Text( - text = uiState.location?.city ?: "", - style = MaterialTheme.typography.headlineLarge, - color = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.padding(horizontal = Dimens.sideMargin) - ) - LocationInfo( - onToggleTunnelInfo = onToggleTunnelInfo, - isVisible = - uiState.tunnelRealState != TunnelState.Disconnected && - uiState.location?.hostname != null, - isExpanded = uiState.isTunnelInfoExpanded, - location = uiState.location, - inAddress = uiState.inAddress, - outAddress = uiState.outAddress, - modifier = - Modifier.fillMaxWidth() - .padding(horizontal = Dimens.sideMargin) - .testTag(LOCATION_INFO_TEST_TAG) - ) - Spacer(modifier = Modifier.height(Dimens.buttonSeparation)) - SwitchLocationButton( - modifier = - Modifier.fillMaxWidth() - .height(Dimens.selectLocationButtonHeight) - .padding(horizontal = Dimens.sideMargin) - .testTag(SELECT_LOCATION_BUTTON_TEST_TAG), - onClick = onSwitchLocationClick, - showChevron = uiState.showLocation, - text = - if (uiState.showLocation) { - uiState.relayLocation?.locationName ?: "" - } else { - stringResource(id = R.string.switch_location) - } - ) - Spacer(modifier = Modifier.height(Dimens.buttonSeparation)) - ConnectionButton( - state = uiState.tunnelUiState, - modifier = - Modifier.fillMaxWidth() - .height(Dimens.connectButtonHeight) - .padding(horizontal = Dimens.sideMargin) - .testTag(CONNECT_BUTTON_TEST_TAG), - disconnectClick = onDisconnectClick, - reconnectClick = { handleThrottledAction(onReconnectClick) }, - cancelClick = onCancelClick, - connectClick = { handleThrottledAction(onConnectClick) }, - reconnectButtonTestTag = RECONNECT_BUTTON_TEST_TAG - ) } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt index d83941e4de..7592be144b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt @@ -8,21 +8,12 @@ import android.view.View import android.view.ViewGroup import androidx.compose.runtime.collectAsState import androidx.compose.ui.platform.ComposeView -import androidx.core.content.ContextCompat -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.screen.ConnectScreen -import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.lib.common.util.appendHideNavOnReleaseBuild import net.mullvad.mullvadvpn.lib.theme.AppTheme -import net.mullvad.mullvadvpn.model.TunnelState +import net.mullvad.mullvadvpn.ui.MainActivity import net.mullvad.mullvadvpn.ui.NavigationBarPainter -import net.mullvad.mullvadvpn.ui.paintNavigationBar -import net.mullvad.mullvadvpn.ui.widget.HeaderBar import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel import org.koin.androidx.viewmodel.ext.android.viewModel @@ -31,26 +22,12 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter { // Injected dependencies private val connectViewModel: ConnectViewModel by viewModel() - private lateinit var headerBar: HeaderBar - - @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - lifecycleScope.launchUiSubscriptionsOnResume() - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - val view = inflater.inflate(R.layout.connect, container, false) - - headerBar = - view.findViewById<HeaderBar>(R.id.header_bar).apply { - tunnelState = connectViewModel.uiState.value.tunnelUiState - } + val view = inflater.inflate(R.layout.fragment_compose, container, false) view.findViewById<ComposeView>(R.id.compose_view).setContent { AppTheme { @@ -62,11 +39,13 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter { onReconnectClick = connectViewModel::onReconnectClick, onConnectClick = connectViewModel::onConnectClick, onCancelClick = connectViewModel::onCancelClick, - onSwitchLocationClick = { openSwitchLocationScreen() }, + onSwitchLocationClick = ::openSwitchLocationScreen, onToggleTunnelInfo = connectViewModel::toggleTunnelInfoExpansion, onUpdateVersionClick = { openDownloadUrl() }, onManageAccountClick = connectViewModel::onManageAccountClick, - onOpenOutOfTimeScreen = ::openOutOfTimeScreen + onOpenOutOfTimeScreen = ::openOutOfTimeScreen, + onSettingsClick = ::openSettingsView, + onAccountClick = ::openAccountView ) } } @@ -74,11 +53,6 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter { return view } - override fun onResume() { - super.onResume() - paintNavigationBar(ContextCompat.getColor(requireContext(), R.color.blue)) - } - private fun openDownloadUrl() { val intent = Intent( @@ -93,18 +67,6 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter { requireContext().startActivity(intent) } - private fun CoroutineScope.launchUiSubscriptionsOnResume() = launch { - repeatOnLifecycle(Lifecycle.State.RESUMED) { launchViewModelSubscription() } - } - - private fun CoroutineScope.launchViewModelSubscription() = launch { - connectViewModel.uiState.collect { uiState -> updateTunnelState(uiState.tunnelRealState) } - } - - private fun updateTunnelState(realState: TunnelState) { - headerBar.tunnelState = realState - } - private fun openSwitchLocationScreen() { parentFragmentManager.beginTransaction().apply { setCustomAnimations( @@ -125,4 +87,12 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter { commitAllowingStateLoss() } } + + private fun openSettingsView() { + (context as? MainActivity)?.openSettings() + } + + private fun openAccountView() { + (context as? MainActivity)?.openAccount() + } } diff --git a/android/app/src/main/res/layout/connect.xml b/android/app/src/main/res/layout/connect.xml deleted file mode 100644 index 7c0267d903..0000000000 --- a/android/app/src/main/res/layout/connect.xml +++ /dev/null @@ -1,14 +0,0 @@ -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:orientation="vertical"> - <net.mullvad.mullvadvpn.ui.widget.HeaderBar android:id="@+id/header_bar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:elevation="0.5dp" /> - <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - app:layout_behavior="net.mullvad.mullvadvpn.ui.UnderNotificationBannerBehavior" /> -</LinearLayout> |
