summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-09-03 07:15:41 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-09-03 07:15:41 -0300
commitbc13c536704710abda42aa6d5249a30a42c6ad93 (patch)
tree9fe190877e8f26f09c9024e22cc0bde52a4797d6 /android
parent8edecd78260795bd9eeaf620b8b02d35bd2c7130 (diff)
parent1d83873e1739af94670453a6c3107f5a509cf35c (diff)
downloadmullvadvpn-bc13c536704710abda42aa6d5249a30a42c6ad93.tar.xz
mullvadvpn-bc13c536704710abda42aa6d5249a30a42c6ad93.zip
Merge branch 'create-switch-location-widget'
Diffstat (limited to 'android')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectFragment.kt15
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SwitchLocationButton.kt118
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt89
-rw-r--r--android/src/main/res/layout/connect.xml10
-rw-r--r--android/src/main/res/layout/switch_location_button.xml14
-rw-r--r--android/src/main/res/values/dimensions.xml3
-rw-r--r--android/src/main/res/values/styles.xml3
7 files changed, 119 insertions, 133 deletions
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 30794f0eec..b1a4f6f2cb 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectFragment.kt
@@ -13,6 +13,7 @@ import net.mullvad.mullvadvpn.ui.notification.TunnelStateNotification
import net.mullvad.mullvadvpn.ui.notification.VersionInfoNotification
import net.mullvad.mullvadvpn.ui.widget.HeaderBar
import net.mullvad.mullvadvpn.ui.widget.NotificationBanner
+import net.mullvad.mullvadvpn.ui.widget.SwitchLocationButton
import org.joda.time.DateTime
val KEY_IS_TUNNEL_INFO_EXPANDED = "is_tunnel_info_expanded"
@@ -68,8 +69,9 @@ class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) {
onDisconnect = { connectionProxy.disconnect() }
}
- switchLocationButton = SwitchLocationButton(view, resources)
- switchLocationButton.onClick = { openSwitchLocationScreen() }
+ switchLocationButton = view.findViewById<SwitchLocationButton>(R.id.switch_location).apply {
+ onClick = { openSwitchLocationScreen() }
+ }
return view
}
@@ -86,8 +88,10 @@ class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) {
}
relayListListener.onRelayListChange = { _, selectedRelayItem ->
- locationInfoCache.selectedRelay = selectedRelayItem
- switchLocationButton.location = selectedRelayItem
+ jobTracker.newUiJob("updateSelectedRelayItem") {
+ locationInfoCache.selectedRelay = selectedRelayItem
+ switchLocationButton.location = selectedRelayItem
+ }
}
connectionProxy.onUiStateChange.subscribe(this) { uiState ->
@@ -120,7 +124,6 @@ class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) {
override fun onSafelyDestroyView() {
notificationBanner.onDestroy()
- switchLocationButton.onDestroy()
}
override fun onSafelySaveInstanceState(state: Bundle) {
@@ -134,7 +137,7 @@ class ConnectFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) {
status.setState(realState)
actionButton.tunnelState = uiState
- switchLocationButton.state = uiState
+ switchLocationButton.tunnelState = uiState
}
private fun openSwitchLocationScreen() {
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SwitchLocationButton.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SwitchLocationButton.kt
deleted file mode 100644
index 89eaf2cad8..0000000000
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/SwitchLocationButton.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-package net.mullvad.mullvadvpn.ui
-
-import android.content.res.Resources
-import android.graphics.drawable.Drawable
-import android.text.TextUtils.TruncateAt
-import android.view.View
-import android.view.ViewGroup.MarginLayoutParams
-import android.widget.Button
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.model.TunnelState
-import net.mullvad.mullvadvpn.relaylist.RelayItem
-import net.mullvad.talpid.tunnel.ActionAfterDisconnect
-
-class SwitchLocationButton(val parentView: View, val resources: Resources) {
- private val button: Button = parentView.findViewById(R.id.switch_location)
- private val chevron: Drawable = button.compoundDrawables[2]
-
- private val normalButtonHeight = resources.getDimensionPixelSize(R.dimen.normal_button_height)
- private val tallButtonHeight = resources.getDimensionPixelSize(R.dimen.tall_button_height)
- private val topMargin = tallButtonHeight - normalButtonHeight
-
- private var tall = false
- private var updateJob: Job? = null
-
- var location: RelayItem? = null
- set(value) {
- field = value
- update()
- }
-
- var state: TunnelState = TunnelState.Disconnected()
- set(value) {
- field = value
- update()
- }
-
- var onClick: (() -> Unit)? = null
-
- init {
- button.setOnClickListener { onClick?.invoke() }
- button.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> resizeIfNecessary() }
- }
-
- fun onDestroy() {
- updateJob?.cancel()
- }
-
- private fun update() {
- updateJob?.cancel()
- updateJob = GlobalScope.launch(Dispatchers.Main) {
- val state = this@SwitchLocationButton.state
-
- when (state) {
- is TunnelState.Disconnected -> showLocation()
- is TunnelState.Disconnecting -> {
- when (state.actionAfterDisconnect) {
- ActionAfterDisconnect.Nothing -> showLocation()
- ActionAfterDisconnect.Block -> showLocation()
- ActionAfterDisconnect.Reconnect -> showLabel()
- }
- }
- is TunnelState.Connecting -> showLabel()
- is TunnelState.Connected -> showLabel()
- is TunnelState.Error -> showLocation()
- }
- }
- }
-
- private fun showLabel() {
- button.setText(R.string.switch_location)
- button.setCompoundDrawables(null, null, null, null)
- resizeIfNecessary()
- }
-
- private fun showLocation() {
- val locationName = location?.locationName
-
- if (locationName == null) {
- showLabel()
- } else {
- button.setText(locationName)
- button.setCompoundDrawables(null, null, chevron, null)
- resizeIfNecessary()
- }
- }
-
- private fun resizeIfNecessary() {
- val layoutParams = button.layoutParams
-
- if (button.lineCount > 1 && !tall) {
- tall = true
-
- if (layoutParams is MarginLayoutParams) {
- layoutParams.height = tallButtonHeight
- layoutParams.topMargin = 0
- }
-
- button.maxLines = 2
- button.ellipsize = TruncateAt.END
- button.requestLayout()
- } else if (button.lineCount <= 1 && tall) {
- tall = false
-
- if (layoutParams is MarginLayoutParams) {
- layoutParams.height = normalButtonHeight
- layoutParams.topMargin = topMargin
- }
-
- button.maxLines = -1
- button.ellipsize = null
- button.requestLayout()
- }
- }
-}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt
new file mode 100644
index 0000000000..9ca390b4e1
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt
@@ -0,0 +1,89 @@
+package net.mullvad.mullvadvpn.ui.widget
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.FrameLayout
+import android.widget.TextView
+import kotlin.properties.Delegates.observable
+import net.mullvad.mullvadvpn.R
+import net.mullvad.mullvadvpn.model.TunnelState
+import net.mullvad.mullvadvpn.relaylist.RelayItem
+import net.mullvad.talpid.tunnel.ActionAfterDisconnect
+
+class SwitchLocationButton : FrameLayout {
+ private val container =
+ context.getSystemService(Context.LAYOUT_INFLATER_SERVICE).let { service ->
+ val inflater = service as LayoutInflater
+
+ inflater.inflate(R.layout.switch_location_button, this)
+ }
+
+ private val buttonWithLabel = container.findViewById<View>(R.id.button_with_label).apply {
+ setOnClickListener { onClick?.invoke() }
+ }
+
+ private val buttonWithLocation =
+ container.findViewById<TextView>(R.id.button_with_location).apply {
+ setOnClickListener { onClick?.invoke() }
+ }
+
+ var onClick: (() -> Unit)? = null
+
+ var location by observable<RelayItem?>(null) { _, _, location ->
+ buttonWithLocation.text = location?.locationName ?: ""
+ }
+
+ var tunnelState by observable<TunnelState>(TunnelState.Disconnected()) { _, _, state ->
+ when (state) {
+ is TunnelState.Disconnected -> showLocation()
+ is TunnelState.Disconnecting -> {
+ when (state.actionAfterDisconnect) {
+ ActionAfterDisconnect.Nothing -> showLocation()
+ ActionAfterDisconnect.Block -> showLocation()
+ ActionAfterDisconnect.Reconnect -> showLabel()
+ }
+ }
+ is TunnelState.Connecting -> showLabel()
+ is TunnelState.Connected -> showLabel()
+ is TunnelState.Error -> showLocation()
+ }
+ }
+
+ 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) {}
+
+ private fun showLabel() {
+ updateButton(buttonWithLabel, true)
+ updateButton(buttonWithLocation, false)
+ }
+
+ private fun showLocation() {
+ updateButton(buttonWithLabel, false)
+ updateButton(buttonWithLocation, true)
+ }
+
+ private fun updateButton(button: View, show: Boolean) {
+ button.apply {
+ setEnabled(show)
+
+ visibility = if (show) {
+ View.VISIBLE
+ } else {
+ View.INVISIBLE
+ }
+ }
+ }
+}
diff --git a/android/src/main/res/layout/connect.xml b/android/src/main/res/layout/connect.xml
index a7887e5076..7fd06fd4bc 100644
--- a/android/src/main/res/layout/connect.xml
+++ b/android/src/main/res/layout/connect.xml
@@ -121,12 +121,10 @@
android:paddingHorizontal="@dimen/side_margin"
android:paddingTop="@dimen/button_separation"
android:paddingBottom="@dimen/screen_vertical_margin">
- <Button android:id="@+id/switch_location"
- android:layout_marginBottom="@dimen/button_separation"
- android:paddingHorizontal="9dp"
- android:text="@string/switch_location"
- android:drawableRight="@drawable/icon_chevron"
- style="@style/White20Button" />
+ <net.mullvad.mullvadvpn.ui.widget.SwitchLocationButton android:id="@+id/switch_location"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/button_separation" />
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
diff --git a/android/src/main/res/layout/switch_location_button.xml b/android/src/main/res/layout/switch_location_button.xml
new file mode 100644
index 0000000000..d9ed79956f
--- /dev/null
+++ b/android/src/main/res/layout/switch_location_button.xml
@@ -0,0 +1,14 @@
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+ <Button android:id="@+id/button_with_label"
+ android:layout_gravity="bottom"
+ android:paddingHorizontal="9dp"
+ android:text="@string/switch_location"
+ style="@style/White20Button" />
+ <Button android:id="@+id/button_with_location"
+ android:layout_gravity="bottom"
+ android:paddingHorizontal="9dp"
+ android:text="@string/switch_location"
+ android:drawableRight="@drawable/icon_chevron"
+ android:visibility="invisible"
+ style="@style/White20Button" />
+</merge>
diff --git a/android/src/main/res/values/dimensions.xml b/android/src/main/res/values/dimensions.xml
index 1d87dc8350..0e4240ef36 100644
--- a/android/src/main/res/values/dimensions.xml
+++ b/android/src/main/res/values/dimensions.xml
@@ -7,8 +7,7 @@
<dimen name="account_input_corner_radius">4dp</dimen>
<dimen name="account_input_border_width">2dp</dimen>
<dimen name="edit_text_corner_radius">4dp</dimen>
- <dimen name="normal_button_height">44dp</dimen>
- <dimen name="tall_button_height">64dp</dimen>
+ <dimen name="button_height">44dp</dimen>
<dimen name="cell_switch_border_radius">16dp</dimen>
<dimen name="cell_switch_width">48dp</dimen>
<dimen name="cell_switch_height">30dp</dimen>
diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml
index e5f8ea91db..1fc47c0e6f 100644
--- a/android/src/main/res/values/styles.xml
+++ b/android/src/main/res/values/styles.xml
@@ -15,8 +15,9 @@
</style>
<style name="Button"
parent="Widget.AppCompat.Button.Borderless">
- <item name="android:layout_height">@dimen/normal_button_height</item>
+ <item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">match_parent</item>
+ <item name="android:minHeight">@dimen/button_height</item>
<item name="android:paddingTop">0dp</item>
<item name="android:paddingBottom">0dp</item>
<item name="android:textAllCaps">false</item>