diff options
author | Torsten Grote <t@grobox.de> | 2020-07-17 14:46:09 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-07-17 15:14:14 -0300 |
commit | aa4472c62acd909cea65dd26102b5d7188c7aacd (patch) | |
tree | 930a4705a2437e82deec7991678aeec2b4f38712 /wallet | |
parent | 1c8da5aea284a0299840721afc86dae75b16ba78 (diff) | |
download | taler-android-aa4472c62acd909cea65dd26102b5d7188c7aacd.tar.gz taler-android-aa4472c62acd909cea65dd26102b5d7188c7aacd.tar.bz2 taler-android-aa4472c62acd909cea65dd26102b5d7188c7aacd.zip |
[wallet] Allow to add an exchange manually by providing its base URL
Diffstat (limited to 'wallet')
10 files changed, 184 insertions, 19 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/AddExchangeDialogFragment.kt b/wallet/src/main/java/net/taler/wallet/exchanges/AddExchangeDialogFragment.kt new file mode 100644 index 0000000..5ea763a --- /dev/null +++ b/wallet/src/main/java/net/taler/wallet/exchanges/AddExchangeDialogFragment.kt @@ -0,0 +1,49 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +package net.taler.wallet.exchanges + +import android.app.Dialog +import android.os.Bundle +import android.widget.TextView +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.activityViewModels +import net.taler.wallet.MainViewModel +import net.taler.wallet.R + + +class AddExchangeDialogFragment : DialogFragment() { + + private val model: MainViewModel by activityViewModels() + private val exchangeManager by lazy { model.exchangeManager } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return AlertDialog.Builder(requireContext(), R.style.DialogTheme) + .setIcon(R.drawable.ic_account_balance) + .setTitle(R.string.exchange_list_add) + .setView(R.layout.dialog_exchange_add) + .setPositiveButton(R.string.ok) { dialog, _ -> + val urlView: TextView = (dialog as AlertDialog).findViewById(R.id.urlView)!! + exchangeManager.add(urlView.text.toString()) + } + .setNegativeButton(R.string.cancel) { _, _ -> + dismiss() + } + .create() + } + +} diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt index 9d0c493..c844042 100644 --- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt @@ -20,12 +20,15 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast +import android.widget.Toast.LENGTH_LONG import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.android.synthetic.main.fragment_exchange_list.* +import net.taler.common.EventObserver import net.taler.common.fadeIn import net.taler.common.fadeOut import net.taler.wallet.MainViewModel @@ -49,20 +52,34 @@ class ExchangeListFragment : Fragment() { adapter = exchangeAdapter addItemDecoration(DividerItemDecoration(context, LinearLayoutManager.VERTICAL)) } + addExchangeFab.setOnClickListener { + AddExchangeDialogFragment().show(parentFragmentManager, "ADD_EXCHANGE") + } exchangeManager.progress.observe(viewLifecycleOwner, Observer { show -> if (show) progressBar.fadeIn() else progressBar.fadeOut() }) exchangeManager.exchanges.observe(viewLifecycleOwner, Observer { exchanges -> - exchangeAdapter.update(exchanges) - if (exchanges.isEmpty()) { - emptyState.fadeIn() - list.fadeOut() - } else { - emptyState.fadeOut() - list.fadeIn() - } + onExchangeUpdate(exchanges) + }) + exchangeManager.addError.observe(viewLifecycleOwner, EventObserver { error -> + if (error) onAddExchangeFailed() }) } + private fun onExchangeUpdate(exchanges: List<ExchangeItem>) { + exchangeAdapter.update(exchanges) + if (exchanges.isEmpty()) { + emptyState.fadeIn() + list.fadeOut() + } else { + emptyState.fadeOut() + list.fadeIn() + } + } + + private fun onAddExchangeFailed() { + Toast.makeText(requireContext(), R.string.exchange_add_error, LENGTH_LONG).show() + } + } diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt index fe8ac76..4b93c40 100644 --- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt +++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt @@ -21,6 +21,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue +import net.taler.common.Event +import net.taler.common.toEvent import net.taler.wallet.TAG import net.taler.wallet.backend.WalletBackendApi import org.json.JSONObject @@ -36,13 +38,20 @@ class ExchangeManager( private val mExchanges = MutableLiveData<List<ExchangeItem>>() val exchanges: LiveData<List<ExchangeItem>> get() = list() + private val mAddError = MutableLiveData<Event<Boolean>>() + val addError: LiveData<Event<Boolean>> = mAddError + fun add(exchangeUrl: String) { + mProgress.value = true val args = JSONObject().apply { put("exchangeBaseUrl", exchangeUrl) } walletBackendApi.sendRequest("addExchange", args) { isError, result -> + mProgress.value = false if (isError) { - Log.e(TAG, "add Error: $result") + Log.e(TAG, "$result") + mAddError.value = true.toEvent() } else { - Log.e(TAG, "add Success: $result") + Log.d(TAG, "Exchange $exchangeUrl added") + list() } } } @@ -54,7 +63,7 @@ class ExchangeManager( throw AssertionError("Wallet core failed to return exchanges!") } else { val exchanges: List<ExchangeItem> = mapper.readValue(result.getString("exchanges")) - Log.e(TAG, "list Success: $exchanges") + Log.d(TAG, "Exchange list: $exchanges") mProgress.value = false mExchanges.value = exchanges } diff --git a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt index 31295d6..d9b1def 100644 --- a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt @@ -110,7 +110,7 @@ class SettingsFragment : PreferenceFragmentCompat() { } private fun showResetDialog() { - AlertDialog.Builder(requireContext()) + AlertDialog.Builder(requireContext(), R.style.DialogTheme) .setMessage("Do you really want to reset the wallet and lose all coins and purchases?") .setPositiveButton("Reset") { _, _ -> model.dangerouslyReset() diff --git a/wallet/src/main/res/drawable/ic_baseline_add.xml b/wallet/src/main/res/drawable/ic_baseline_add.xml new file mode 100644 index 0000000..d123476 --- /dev/null +++ b/wallet/src/main/res/drawable/ic_baseline_add.xml @@ -0,0 +1,26 @@ +<!-- + ~ This file is part of GNU Taler + ~ (C) 2020 Taler Systems S.A. + ~ + ~ GNU Taler is free software; you can redistribute it and/or modify it under the + ~ terms of the GNU General Public License as published by the Free Software + ~ Foundation; either version 3, or (at your option) any later version. + ~ + ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + ~ A PARTICULAR PURPOSE. See the GNU General Public License for more details. + ~ + ~ You should have received a copy of the GNU General Public License along with + ~ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorControlNormal" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" /> +</vector> diff --git a/wallet/src/main/res/layout/dialog_exchange_add.xml b/wallet/src/main/res/layout/dialog_exchange_add.xml new file mode 100644 index 0000000..dfa0f70 --- /dev/null +++ b/wallet/src/main/res/layout/dialog_exchange_add.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ This file is part of GNU Taler + ~ (C) 2020 Taler Systems S.A. + ~ + ~ GNU Taler is free software; you can redistribute it and/or modify it under the + ~ terms of the GNU General Public License as published by the Free Software + ~ Foundation; either version 3, or (at your option) any later version. + ~ + ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + ~ A PARTICULAR PURPOSE. See the GNU General Public License for more details. + ~ + ~ You should have received a copy of the GNU General Public License along with + ~ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + --> + +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/urlLayout" + style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:hint="@string/exchange_add_url" + app:boxBackgroundMode="outline" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/urlView" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inputType="textUri" + android:text="https://" + tools:ignore="HardcodedText" /> + + </com.google.android.material.textfield.TextInputLayout> + +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/wallet/src/main/res/layout/fragment_exchange_list.xml b/wallet/src/main/res/layout/fragment_exchange_list.xml index e08901e..c7404ae 100644 --- a/wallet/src/main/res/layout/fragment_exchange_list.xml +++ b/wallet/src/main/res/layout/fragment_exchange_list.xml @@ -49,4 +49,13 @@ android:visibility="invisible" tools:visibility="visible" /> + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/addExchangeFab" + style="@style/FabStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:contentDescription="@string/exchange_list_add" + android:src="@drawable/ic_baseline_add" + app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" /> + </androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/wallet/src/main/res/layout/fragment_main.xml b/wallet/src/main/res/layout/fragment_main.xml index 81121b5..3f680ba 100644 --- a/wallet/src/main/res/layout/fragment_main.xml +++ b/wallet/src/main/res/layout/fragment_main.xml @@ -25,16 +25,11 @@ <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/mainFab" + style="@style/FabStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="bottom|end" - android:layout_marginEnd="16dp" - android:layout_marginBottom="16dp" android:contentDescription="@string/button_scan_qr_code" android:src="@drawable/ic_scan_qr" - app:backgroundTint="@color/colorPrimary" - app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" - app:layout_dodgeInsetEdges="bottom" - app:tint="?attr/colorOnPrimary" /> + app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml index 79a3630..226c7d1 100644 --- a/wallet/src/main/res/values/strings.xml +++ b/wallet/src/main/res/values/strings.xml @@ -50,6 +50,7 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card <string name="paste_invalid">Clipboard contains an invalid data type</string> <string name="uri_invalid">Not a valid Taler URI</string> <string name="ok">OK</string> + <string name="cancel">Cancel</string> <string name="search">Search</string> <string name="menu_settings">Settings</string> @@ -117,6 +118,9 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card <string name="exchange_list_title">Exchanges</string> <string name="exchange_list_empty">No exchanges known\n\nAdd one manually or withdraw digital cash!</string> <string name="exchange_list_currency">Currency: %s</string> + <string name="exchange_list_add">Add exchange</string> + <string name="exchange_add_url">Enter address of exchange</string> + <string name="exchange_add_error">Could not add exchange</string> <string name="exchange_fee_withdrawal_fee_label">Withdrawal Fee:</string> <string name="exchange_fee_overhead_label">Rounding Loss:</string> diff --git a/wallet/src/main/res/values/styles.xml b/wallet/src/main/res/values/styles.xml index 093f43f..33e31a3 100644 --- a/wallet/src/main/res/values/styles.xml +++ b/wallet/src/main/res/values/styles.xml @@ -35,6 +35,8 @@ <style name="AppTheme.Toolbar" parent="Widget.MaterialComponents.Toolbar.Primary" /> + <style name="DialogTheme" parent="Theme.MaterialComponents.DayNight.Dialog.Alert" /> + <style name="TransactionTitle"> <item name="android:textSize">16sp</item> <item name="android:textColor">?android:textColorPrimary</item> @@ -70,4 +72,13 @@ <item name="cardElevation">8dp</item> </style> + <style name="FabStyle" parent="Widget.MaterialComponents.FloatingActionButton"> + <item name="android:layout_gravity">bottom|end</item> + <item name="android:layout_marginEnd">16dp</item> + <item name="android:layout_marginBottom">16dp</item> + <item name="backgroundTint">@color/colorPrimary</item> + <item name="layout_dodgeInsetEdges">bottom</item> + <item name="tint">?attr/colorOnPrimary</item> + </style> + </resources> |