diff options
| author | Aleksandr Granin <aleksandr@mullvad.net> | 2021-03-02 09:44:55 +0100 |
|---|---|---|
| committer | Aleksandr Granin <aleksandr@mullvad.net> | 2021-03-02 09:44:55 +0100 |
| commit | 946113d1ce9be660990bdd4bb6e4c023166bcee6 (patch) | |
| tree | 479ec622228f789d7be20efb00d1d991a6c43dc6 /android | |
| parent | 117cb654c7aba8785ce719da5ea13be5c9655e4b (diff) | |
| parent | 9ade3b0b7f85ed5aa281139455a580876a825c23 (diff) | |
| download | mullvadvpn-946113d1ce9be660990bdd4bb6e4c023166bcee6.tar.xz mullvadvpn-946113d1ce9be660990bdd4bb6e4c023166bcee6.zip | |
Merge branch 'systembars-themes'
Diffstat (limited to 'android')
17 files changed, 109 insertions, 48 deletions
diff --git a/android/build.gradle b/android/build.gradle index 1c12f86150..407a680258 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -100,8 +100,10 @@ repositories { dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' + implementation "androidx.fragment:fragment-ktx:1.3.0" + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.0" implementation 'androidx.recyclerview:recyclerview:1.1.0' - implementation 'com.google.android.material:material:1.2.1' + implementation 'com.google.android.material:material:1.3.0' implementation 'commons-validator:commons-validator:1.7' implementation 'joda-time:joda-time:2.10.2' implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.4.10' diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountFragment.kt index b2da9f9f2f..5cb2da2152 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountFragment.kt @@ -74,7 +74,7 @@ class AccountFragment : ServiceDependentFragment(OnNoService.GoBack) { } redeemVoucherButton = view.findViewById<RedeemVoucherButton>(R.id.redeem_voucher).apply { - prepare(fragmentManager, jobTracker) + prepare(parentFragmentManager, jobTracker) } view.findViewById<Button>(R.id.logout).setOnClickAction("logout", jobTracker) { @@ -147,7 +147,7 @@ class AccountFragment : ServiceDependentFragment(OnNoService.GoBack) { } private fun showRedeemVoucherDialog() { - val transaction = requireFragmentManager().beginTransaction() + val transaction = parentFragmentManager.beginTransaction() transaction.addToBackStack(null) @@ -167,7 +167,7 @@ class AccountFragment : ServiceDependentFragment(OnNoService.GoBack) { } private fun clearBackStack() { - fragmentManager?.apply { + parentFragmentManager.apply { val firstEntry = getBackStackEntryAt(0) popBackStack(firstEntry.id, FragmentManager.POP_BACK_STACK_INCLUSIVE) @@ -175,7 +175,7 @@ class AccountFragment : ServiceDependentFragment(OnNoService.GoBack) { } private fun goToLoginScreen() { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { setCustomAnimations( R.anim.do_nothing, R.anim.fragment_exit_to_bottom, diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AdvancedFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AdvancedFragment.kt index b7b9445cbe..4f4210be70 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AdvancedFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AdvancedFragment.kt @@ -124,7 +124,7 @@ class AdvancedFragment : ServiceDependentFragment(OnNoService.GoBack) { } private fun showConfirmPublicDnsServerDialog(confirmation: CompletableDeferred<Boolean>) { - val transaction = requireFragmentManager().beginTransaction() + val transaction = parentFragmentManager.beginTransaction() detachBackButtonHandler() transaction.addToBackStack(null) diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectFragment.kt index c4b06ebd95..669344b3bf 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.content.ContextCompat import kotlinx.coroutines.delay import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.model.TunnelState @@ -18,7 +19,8 @@ import org.joda.time.DateTime val KEY_IS_TUNNEL_INFO_EXPANDED = "is_tunnel_info_expanded" -class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { +class ConnectFragment : + ServiceDependentFragment(OnNoService.GoToLaunchScreen), NavigationBarPainter { private lateinit var actionButton: ConnectActionButton private lateinit var switchLocationButton: SwitchLocationButton private lateinit var headerBar: HeaderBar @@ -57,7 +59,7 @@ class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { status = ConnectionStatus(view, parentActivity) - locationInfo = LocationInfo(view, context!!) + locationInfo = LocationInfo(view, requireContext()) locationInfo.isTunnelInfoExpanded = isTunnelInfoExpanded actionButton = ConnectActionButton(view) @@ -130,6 +132,11 @@ class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { state.putBoolean(KEY_IS_TUNNEL_INFO_EXPANDED, isTunnelInfoExpanded) } + override fun onResume() { + super.onResume() + paintNavigationBar(ContextCompat.getColor(requireContext(), R.color.blue)) + } + private fun updateTunnelState(uiState: TunnelState, realState: TunnelState) { locationInfo.state = realState headerBar.tunnelState = realState @@ -140,7 +147,7 @@ class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { } private fun openSwitchLocationScreen() { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { setCustomAnimations( R.anim.fragment_enter_from_bottom, R.anim.do_nothing, @@ -155,7 +162,7 @@ class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { private fun openOutOfTimeScreen() { jobTracker.newUiJob("openOutOfTimeScreen") { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { replace(R.id.main_fragment, OutOfTimeFragment()) commit() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LaunchFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LaunchFragment.kt index ac4470520f..8e665dad01 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LaunchFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LaunchFragment.kt @@ -52,14 +52,14 @@ class LaunchFragment : ServiceAwareFragment() { } private fun advanceToLoginScreen() { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { replace(R.id.main_fragment, LoginFragment()) commit() } } private fun advanceToConnectScreen() { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { replace(R.id.main_fragment, ConnectFragment()) commit() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt index 528524ac23..b893b6406c 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt @@ -208,7 +208,7 @@ class LoginFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { } private fun openNextScreen(fragment: Fragment) { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { replace(R.id.main_fragment, fragment) commit() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt index c1be537c71..89df0bbedb 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt @@ -204,6 +204,7 @@ open class MainActivity : FragmentActivity() { } } + @Suppress("DEPRECATION") fun requestVpnPermission(intent: Intent) { startActivityForResult(intent, 0) } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/NavigationBarPainter.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/NavigationBarPainter.kt new file mode 100644 index 0000000000..1047793f6f --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/NavigationBarPainter.kt @@ -0,0 +1,10 @@ +package net.mullvad.mullvadvpn.ui + +import android.app.Activity +import androidx.annotation.ColorInt + +interface NavigationBarPainter : SystemPainter + +fun NavigationBarPainter.paintNavigationBar(@ColorInt color: Int) { + (getContext() as Activity?)?.window?.navigationBarColor = color +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/OutOfTimeFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/OutOfTimeFragment.kt index fe70519db1..8443d7c530 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/OutOfTimeFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/OutOfTimeFragment.kt @@ -57,7 +57,7 @@ class OutOfTimeFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) } redeemButton = view.findViewById<RedeemVoucherButton>(R.id.redeem_voucher).apply { - prepare(fragmentManager, jobTracker) + prepare(parentFragmentManager, jobTracker) } connectionProxy.onStateChange.subscribe(this) { newState -> @@ -135,7 +135,7 @@ class OutOfTimeFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) } private fun advanceToConnectScreen() { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { replace(R.id.main_fragment, ConnectFragment()) commit() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ProblemReportFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ProblemReportFragment.kt index cd1a64e5ad..d97e3a9ac9 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ProblemReportFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ProblemReportFragment.kt @@ -144,7 +144,7 @@ class ProblemReportFragment : BaseFragment() { } private fun showLogs() { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { setCustomAnimations( R.anim.fragment_enter_from_right, R.anim.fragment_half_exit_to_left, @@ -197,7 +197,7 @@ class ProblemReportFragment : BaseFragment() { } private fun showConfirmNoEmailDialog() { - val transaction = requireFragmentManager().beginTransaction() + val transaction = parentFragmentManager.beginTransaction() transaction.addToBackStack(null) diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt index ddc89d973b..43237dcd25 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt @@ -9,8 +9,11 @@ import android.view.animation.Animation import android.view.animation.Animation.AnimationListener import android.view.animation.AnimationUtils import android.widget.ImageButton +import androidx.core.content.ContextCompat +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.flow.collect import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.model.Constraint import net.mullvad.mullvadvpn.model.KeygenEvent @@ -23,7 +26,8 @@ import net.mullvad.mullvadvpn.relaylist.RelayListAdapter import net.mullvad.mullvadvpn.ui.widget.CustomRecyclerView import net.mullvad.mullvadvpn.util.AdapterWithHeader -class SelectLocationFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { +class SelectLocationFragment : + ServiceDependentFragment(OnNoService.GoToLaunchScreen), StatusBarPainter, NavigationBarPainter { private enum class RelayListState { Initializing, Loading, @@ -130,6 +134,20 @@ class SelectLocationFragment : ServiceDependentFragment(OnNoService.GoToLaunchSc titleController.onDestroy() } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + lifecycleScope.launchWhenResumed { + transitionFinishedFlow.collect { + paintStatusBar(ContextCompat.getColor(requireContext(), R.color.darkBlue)) + } + } + } + + override fun onResume() { + super.onResume() + paintNavigationBar(ContextCompat.getColor(requireContext(), R.color.darkBlue)) + } + fun close() { activity?.onBackPressed() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt index 4f823fada2..5a0bb79cde 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt @@ -5,6 +5,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageButton +import androidx.core.content.ContextCompat +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.flow.collect import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoCache import net.mullvad.mullvadvpn.service.AccountCache @@ -13,7 +16,7 @@ import net.mullvad.mullvadvpn.ui.widget.AccountCell import net.mullvad.mullvadvpn.ui.widget.AppVersionCell import net.mullvad.mullvadvpn.ui.widget.NavigateCell -class SettingsFragment : ServiceAwareFragment() { +class SettingsFragment : ServiceAwareFragment(), StatusBarPainter, NavigationBarPainter { private lateinit var accountMenu: AccountCell private lateinit var appVersionMenu: AppVersionCell private lateinit var preferencesMenu: View @@ -73,6 +76,20 @@ class SettingsFragment : ServiceAwareFragment() { return view } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + lifecycleScope.launchWhenResumed { + transitionFinishedFlow.collect { + paintStatusBar(ContextCompat.getColor(requireContext(), R.color.darkBlue)) + } + } + } + + override fun onResume() { + super.onResume() + paintNavigationBar(ContextCompat.getColor(requireContext(), R.color.darkBlue)) + } + override fun onStart() { super.onStart() diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/StatusBarPainter.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/StatusBarPainter.kt new file mode 100644 index 0000000000..48f94e17b5 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/StatusBarPainter.kt @@ -0,0 +1,10 @@ +package net.mullvad.mullvadvpn.ui + +import android.app.Activity +import androidx.annotation.ColorInt + +interface StatusBarPainter : SystemPainter + +fun StatusBarPainter.paintStatusBar(@ColorInt color: Int) { + (getContext() as Activity?)?.window?.statusBarColor = color +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SystemPainter.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SystemPainter.kt new file mode 100644 index 0000000000..2f0fc32775 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SystemPainter.kt @@ -0,0 +1,7 @@ +package net.mullvad.mullvadvpn.ui + +import android.content.Context + +interface SystemPainter { + fun getContext(): Context? +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/WelcomeFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/WelcomeFragment.kt index a498922911..8d4500c6f2 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/WelcomeFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/WelcomeFragment.kt @@ -47,7 +47,7 @@ class WelcomeFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { } view.findViewById<RedeemVoucherButton>(R.id.redeem_voucher).apply { - prepare(fragmentManager, jobTracker) + prepare(parentFragmentManager, jobTracker) } return view @@ -119,7 +119,7 @@ class WelcomeFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) { } private fun advanceToConnectScreen() { - fragmentManager?.beginTransaction()?.apply { + parentFragmentManager.beginTransaction().apply { replace(R.id.main_fragment, ConnectFragment()) commit() } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt index dbe09ff34b..eb6ba12032 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt @@ -6,22 +6,25 @@ import android.view.Gravity import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout +import androidx.core.content.ContextCompat import kotlin.properties.Delegates.observable import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.ui.MainActivity +import net.mullvad.mullvadvpn.ui.StatusBarPainter +import net.mullvad.mullvadvpn.ui.paintStatusBar -class HeaderBar : LinearLayout { - private val container = - context.getSystemService(Context.LAYOUT_INFLATER_SERVICE).let { service -> - val inflater = service as LayoutInflater +class HeaderBar @JvmOverloads constructor( + context: Context, + attributes: AttributeSet? = null, + defStyleAttr: Int = 0, + defStyleRes: Int = 0 +) : LinearLayout(context, attributes, defStyleAttr, defStyleRes), StatusBarPainter { + private val container = LayoutInflater.from(context).inflate(R.layout.header_bar, this) - inflater.inflate(R.layout.header_bar, this) - } - - private val disabledColor = context.getColor(android.R.color.transparent) - private val securedColor = context.getColor(R.color.green) - private val unsecuredColor = context.getColor(R.color.red) + private val disabledColor = ContextCompat.getColor(context, android.R.color.transparent) + private val securedColor = ContextCompat.getColor(context, R.color.green) + private val unsecuredColor = ContextCompat.getColor(context, R.color.red) var tunnelState by observable<TunnelState?>(null) { _, _, state -> val backgroundColor = when (state) { @@ -40,25 +43,9 @@ class HeaderBar : LinearLayout { } container.setBackgroundColor(backgroundColor) + paintStatusBar(backgroundColor) } - constructor(context: Context) : super(context) {} - - constructor(context: Context, attributes: AttributeSet) : super(context, attributes) {} - - constructor( - context: Context, - attributes: AttributeSet, - defaultStyleAttribute: Int - ) : super(context, attributes, defaultStyleAttribute) {} - - constructor( - context: Context, - attributes: AttributeSet, - defaultStyleAttribute: Int, - defaultStyleResource: Int - ) : super(context, attributes, defaultStyleAttribute, defaultStyleResource) {} - init { gravity = Gravity.CENTER_VERTICAL orientation = HORIZONTAL diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml index 738b4d951a..d85ee24363 100644 --- a/android/src/main/res/values/styles.xml +++ b/android/src/main/res/values/styles.xml @@ -2,6 +2,8 @@ <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <item name="colorPrimary">@color/colorPrimary</item> + <item name="android:navigationBarColor">@color/blue</item> + <item name="android:statusBarColor">@color/blue</item> <item name="android:windowBackground">@color/blue</item> <item name="switchStyle">@style/AppTheme.Switch</item> </style> |
