summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorEmīls <pinkisemils@mullvad.net>2020-02-11 17:25:27 +0000
committerEmīls <pinkisemils@mullvad.net>2020-02-11 17:25:27 +0000
commit998932a4331310137d01991d6271b09c7c9c35e4 (patch)
tree167d6d815af768eeb911245d23a121958c602ec5 /android/src
parentdc9f4c0c3178d61ef46d2ba784d1cefdd09626ed (diff)
parent3b903818864a75971255b408baa01d6ee9686484 (diff)
downloadmullvadvpn-998932a4331310137d01991d6271b09c7c9c35e4.tar.xz
mullvadvpn-998932a4331310137d01991d6271b09c7c9c35e4.zip
Merge branch 'android-add-account-history'
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt5
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt76
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt15
-rw-r--r--android/src/main/res/drawable/account_history_background.xml16
-rw-r--r--android/src/main/res/drawable/account_history_list_divider.xml5
-rw-r--r--android/src/main/res/layout/account_history_entry.xml13
-rw-r--r--android/src/main/res/layout/login.xml9
7 files changed, 131 insertions, 8 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
index e61567a0fe..a0dabf1a53 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
@@ -45,6 +45,10 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
return getAccountData(daemonInterfaceAddress, accountToken)
}
+ fun getAccountHistory(): ArrayList<String> {
+ return getAccountHistory(daemonInterfaceAddress)
+ }
+
fun getWwwAuthToken(): String {
return getWwwAuthToken(daemonInterfaceAddress)
}
@@ -107,6 +111,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
daemonInterfaceAddress: Long,
accountToken: String
): GetAccountDataResult
+ private external fun getAccountHistory(daemonInterfaceAddress: Long): ArrayList<String>
private external fun getWwwAuthToken(daemonInterfaceAddress: Long): String
private external fun getCurrentLocation(daemonInterfaceAddress: Long): GeoIpLocation?
private external fun getCurrentVersion(daemonInterfaceAddress: Long): String
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt
index 9c8f71667f..0671e51b05 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt
@@ -4,16 +4,22 @@ import android.content.res.Resources
import android.text.Editable
import android.text.TextWatcher
import android.text.style.MetricAffectingSpan
+import android.view.MotionEvent
import android.view.View
-import android.view.View.OnFocusChangeListener
-import android.widget.EditText
+import android.view.View.OnTouchListener
+import android.widget.ArrayAdapter
import android.widget.ImageButton
+import android.widget.ListView
+import android.widget.TextView
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.ui.AccountInputContainer.BorderState
const val MIN_ACCOUNT_TOKEN_LENGTH = 10
-class AccountInput(val parentView: View, val resources: Resources) {
+class AccountInput(
+ val parentView: View,
+ val resources: Resources
+) {
private val disabledBackgroundColor = resources.getColor(R.color.white20)
private val disabledTextColor = resources.getColor(R.color.white)
private val enabledBackgroundColor = resources.getColor(R.color.white)
@@ -24,6 +30,9 @@ class AccountInput(val parentView: View, val resources: Resources) {
set(value) {
field = value
updateBorder()
+ if (value == true) {
+ shouldShowAccountHistory = true
+ }
}
private var usingErrorColor = false
set(value) {
@@ -42,25 +51,49 @@ class AccountInput(val parentView: View, val resources: Resources) {
}
val container: AccountInputContainer = parentView.findViewById(R.id.account_input_container)
- val input: EditText = parentView.findViewById(R.id.account_input)
+ val input: TextView = parentView.findViewById(R.id.account_input)
val button: ImageButton = parentView.findViewById(R.id.login_button)
+ val accountHistoryList: ListView = parentView.findViewById(R.id.account_history_list)
+
+ var accountHistory: ArrayList<String>? = null
+ set(value) {
+ synchronized(this) {
+ field = value
+ updateAccountHistory()
+ }
+ }
+
+ private var shouldShowAccountHistory = false
+ set(value) {
+ synchronized(this) {
+ field = value
+ updateAccountHistory()
+ }
+ }
var onLogin: ((String) -> Unit)? = null
init {
- button.setOnClickListener { onLogin?.invoke(input.text.toString()) }
+ button.setOnClickListener {
+ onLogin?.invoke(input.text.toString())
+ }
setButtonEnabled(false)
input.apply {
addTextChangedListener(InputWatcher())
- onFocusChangeListener = OnFocusChangeListener { view, hasFocus ->
- inputHasFocus = hasFocus && view.isEnabled()
- }
+ setOnTouchListener(OnTouchListener {
+ view, event ->
+ if (MotionEvent.ACTION_UP == event.getAction()) {
+ shouldShowAccountHistory = true
+ }
+ false
+ })
}
container.apply {
clipToOutline = true
outlineProvider = AccountInputOutlineProvider(context)
+ setOnClickListener { shouldShowAccountHistory = true }
}
}
@@ -85,12 +118,14 @@ class AccountInput(val parentView: View, val resources: Resources) {
visibility = View.VISIBLE
clearFocus()
}
+ accountHistoryList.visibility = View.INVISIBLE
}
private fun successState() {
setButtonEnabled(false)
button.visibility = View.GONE
input.visibility = View.GONE
+ container.visibility = View.GONE
}
private fun failureState() {
@@ -117,6 +152,31 @@ class AccountInput(val parentView: View, val resources: Resources) {
}
}
+ private fun updateAccountHistory() {
+ accountHistory?.let { history ->
+ accountHistoryList.apply {
+ setAdapter(ArrayAdapter(context,
+ R.layout.account_history_entry,
+ R.id.account_history_entry_text_view,
+ history))
+
+ setOnItemClickListener { _, _, idx, _ ->
+ val accountNumber = history[idx]
+
+ input.setText(accountNumber)
+ accountHistoryList.visibility = View.GONE
+ onLogin?.invoke(accountNumber)
+ }
+ }
+
+ if (shouldShowAccountHistory && accountHistoryList.visibility != View.VISIBLE) {
+ accountHistoryList.visibility = View.VISIBLE
+ accountHistoryList.translationY = -accountHistoryList.height.toFloat()
+ accountHistoryList.animate().translationY(0.0F).setDuration(350).start()
+ }
+ }
+ }
+
private fun updateBorder() {
if (usingErrorColor) {
container.borderState = BorderState.ERROR
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 434584fb87..7b92118335 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt
@@ -30,6 +30,7 @@ class LoginFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) {
private var loginJob: Deferred<Boolean>? = null
private var advanceToNextScreenJob: Job? = null
+ private var fetchHistoryJob: Job? = null
override fun onSafelyCreateView(
inflater: LayoutInflater,
@@ -51,6 +52,8 @@ class LoginFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) {
view.findViewById<View>(R.id.create_account).setOnClickListener { createAccount() }
+ fetchHistory()
+
return view
}
@@ -59,10 +62,12 @@ class LoginFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) {
loggedIn.join()
openConnectScreen()
}
+ fetchHistory()
}
override fun onSafelyPause() {
advanceToNextScreenJob?.cancel()
+ fetchHistoryJob?.cancel()
}
private fun createAccount() {
@@ -85,6 +90,16 @@ class LoginFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen) {
performLogin(accountToken)
}
+ private fun fetchHistory() {
+ fetchHistoryJob?.cancel()
+ fetchHistoryJob = GlobalScope.launch(Dispatchers.Main) {
+ val history = GlobalScope.async(Dispatchers.Default) {
+ daemon.getAccountHistory()
+ }
+ accountInput.accountHistory = history.await()
+ }
+ }
+
private fun performLogin(accountToken: String) = GlobalScope.launch(Dispatchers.Main) {
loginJob?.cancel()
loginJob = GlobalScope.async(Dispatchers.Default) {
diff --git a/android/src/main/res/drawable/account_history_background.xml b/android/src/main/res/drawable/account_history_background.xml
new file mode 100644
index 0000000000..b71d15464f
--- /dev/null
+++ b/android/src/main/res/drawable/account_history_background.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners android:radius="@dimen/account_input_corner_radius" />
+ <solid android:color="@color/darkBlue" />
+ </shape>
+ </item>
+ <item android:top="0dp" android:right="1dp" android:bottom="1dp"
+ android:left="1dp">
+ <shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners android:radius="@dimen/account_input_corner_radius" />
+ <solid android:color="@color/white" />
+ </shape>
+ </item>
+</layer-list>
diff --git a/android/src/main/res/drawable/account_history_list_divider.xml b/android/src/main/res/drawable/account_history_list_divider.xml
new file mode 100644
index 0000000000..d3b31cc0c3
--- /dev/null
+++ b/android/src/main/res/drawable/account_history_list_divider.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+<solid android:color="@color/darkBlue" />
+</shape>
diff --git a/android/src/main/res/layout/account_history_entry.xml b/android/src/main/res/layout/account_history_entry.xml
new file mode 100644
index 0000000000..f1d0b67bde
--- /dev/null
+++ b/android/src/main/res/layout/account_history_entry.xml
@@ -0,0 +1,13 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView android:id="@+id/account_history_entry_text_view"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:textColor="@color/blue"
+ android:padding="10dip"
+ android:textSize="16dip"
+ android:textStyle="bold"/>
+</LinearLayout>
diff --git a/android/src/main/res/layout/login.xml b/android/src/main/res/layout/login.xml
index b0a53d87d6..46e844d5c6 100644
--- a/android/src/main/res/layout/login.xml
+++ b/android/src/main/res/layout/login.xml
@@ -138,6 +138,15 @@
android:src="@drawable/login_button_arrow"
/>
</net.mullvad.mullvadvpn.ui.AccountInputContainer>
+
+ <ListView android:id="@+id/account_history_list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:divider="@drawable/account_history_list_divider"
+ android:dividerHeight="1dp"
+ android:visibility="invisible"
+ android:background="@drawable/account_history_background"
+ />
<Space
android:layout_width="match_parent"
android:layout_height="0dp"