gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-android] branch master updated (15242d1 -> 1cb54ef)


From: gnunet
Subject: [taler-taler-android] branch master updated (15242d1 -> 1cb54ef)
Date: Tue, 28 Nov 2023 18:32:59 +0100

This is an automated email from the git hooks/post-receive script.

torsten-grote pushed a change to branch master
in repository taler-android.

    from 15242d1  Translated using Weblate (German)
     new 94ee3a2  [wallet] Show KYC notice in transaction list, and don't 
render fees when zero
     new ba51b5e  [wallet] Proper DB import/export functionality
     new 1cb54ef  [wallet] Add confirmation dialog for DB import and i18nize 
some strings

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../main/java/net/taler/wallet/MainViewModel.kt    |  2 +-
 .../net/taler/wallet/backend/WalletBackendApi.kt   | 23 ++++++
 .../wallet/payment/TransactionPaymentComposable.kt | 13 ++--
 .../wallet/refund/TransactionRefundComposable.kt   | 13 ++--
 .../net/taler/wallet/settings/SettingsFragment.kt  | 39 ++++++++--
 .../net/taler/wallet/settings/SettingsManager.kt   | 91 ++++++++++++++++++----
 .../wallet/transactions/TransactionAdapter.kt      | 27 +++++--
 .../withdraw/TransactionWithdrawalComposable.kt    | 13 ++--
 .../list_item_age.xml => drawable/ic_archive.xml}  | 17 ++--
 wallet/src/main/res/values/strings.xml             | 14 +++-
 wallet/src/main/res/xml/settings_main.xml          |  8 ++
 11 files changed, 206 insertions(+), 54 deletions(-)
 copy wallet/src/main/res/{layout/list_item_age.xml => drawable/ic_archive.xml} 
(56%)

diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt 
b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
index 15fe7e4..4614474 100644
--- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
@@ -83,7 +83,7 @@ class MainViewModel(
     val refundManager = RefundManager(api, viewModelScope)
     val exchangeManager: ExchangeManager = ExchangeManager(api, viewModelScope)
     val peerManager: PeerManager = PeerManager(api, exchangeManager, 
viewModelScope)
-    val settingsManager: SettingsManager = 
SettingsManager(app.applicationContext, viewModelScope)
+    val settingsManager: SettingsManager = 
SettingsManager(app.applicationContext, api, viewModelScope)
     val accountManager: AccountManager = AccountManager(api, viewModelScope)
     val depositManager: DepositManager = DepositManager(api, viewModelScope)
 
diff --git a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt 
b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt
index bf6f371..ea58dd7 100644
--- a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt
+++ b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt
@@ -23,6 +23,7 @@ import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import kotlinx.serialization.KSerializer
+import kotlinx.serialization.json.JsonObject
 import kotlinx.serialization.json.decodeFromJsonElement
 import net.taler.wallet.backend.TalerErrorCode.NONE
 import org.json.JSONObject
@@ -86,4 +87,26 @@ class WalletBackendApi(
             WalletResponse.Error(info)
         }
     }
+
+    // Returns raw JSON response instead of serialized object
+    suspend inline fun rawRequest(
+        operation: String,
+        noinline args: (JSONObject.() -> JSONObject)? = null,
+    ): WalletResponse<JsonObject> = withContext(Dispatchers.Default) {
+        val json = BackendManager.json
+        try {
+            when (val response = sendRequest(operation, 
args?.invoke(JSONObject()))) {
+                is ApiResponse.Response -> {
+                    WalletResponse.Success(response.result)
+                }
+                is ApiResponse.Error -> {
+                    val error: TalerErrorInfo = 
json.decodeFromJsonElement(response.error)
+                    WalletResponse.Error(error)
+                }
+            }
+        } catch (e: Exception) {
+            val info = TalerErrorInfo(NONE, "", e.toString())
+            WalletResponse.Error(info)
+        }
+    }
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt 
b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
index c08bc76..7de16b6 100644
--- 
a/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/payment/TransactionPaymentComposable.kt
@@ -83,11 +83,14 @@ fun TransactionPaymentComposable(
             amount = t.amountRaw,
             amountType = AmountType.Neutral,
         )
-        TransactionAmountComposable(
-            label = stringResource(id = R.string.withdraw_fees),
-            amount = t.amountEffective - t.amountRaw,
-            amountType = AmountType.Negative,
-        )
+        val fee = t.amountEffective - t.amountRaw
+        if (!fee.isZero()) {
+            TransactionAmountComposable(
+                label = stringResource(id = R.string.withdraw_fees),
+                amount = fee,
+                amountType = AmountType.Negative,
+            )
+        }
         if (t.posConfirmation != null) {
             TransactionInfoComposable(
                 label = stringResource(id = 
R.string.payment_confirmation_code),
diff --git 
a/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt 
b/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
index ac5e2da..82dceb5 100644
--- 
a/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/refund/TransactionRefundComposable.kt
@@ -79,11 +79,14 @@ fun TransactionRefundComposable(
             amount = t.amountRaw,
             amountType = AmountType.Neutral,
         )
-        TransactionAmountComposable(
-            label = stringResource(id = R.string.withdraw_fees),
-            amount = t.amountRaw - t.amountEffective,
-            amountType = AmountType.Negative,
-        )
+        val fee = t.amountRaw - t.amountEffective
+        if (!fee.isZero()) {
+            TransactionAmountComposable(
+                label = stringResource(id = R.string.withdraw_fees),
+                amount = fee,
+                amountType = AmountType.Negative,
+            )
+        }
         TransactionInfoComposable(
             label = stringResource(id = R.string.transaction_order),
             info = t.paymentInfo?.summary ?: "",
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 f5826c9..f21bd44 100644
--- a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
@@ -18,6 +18,7 @@ package net.taler.wallet.settings
 
 import android.os.Bundle
 import android.view.View
+import androidx.activity.result.contract.ActivityResultContracts.OpenDocument
 import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
 import androidx.fragment.app.activityViewModels
 import androidx.preference.Preference
@@ -47,6 +48,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
     private lateinit var prefWithdrawTest: Preference
     private lateinit var prefLogcat: Preference
     private lateinit var prefExportDb: Preference
+    private lateinit var prefImportDb: Preference
     private lateinit var prefVersionApp: Preference
     private lateinit var prefVersionCore: Preference
     private lateinit var prefVersionExchange: Preference
@@ -58,6 +60,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
             prefWithdrawTest,
             prefLogcat,
             prefExportDb,
+            prefImportDb,
             prefVersionApp,
             prefVersionCore,
             prefVersionExchange,
@@ -71,9 +74,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
         settingsManager.exportLogcat(uri)
     }
     private val dbExportLauncher =
-        registerForActivityResult(CreateDocument("application/x-sqlite3")) { 
uri ->
+        registerForActivityResult(CreateDocument("application/json")) { uri ->
             settingsManager.exportDb(uri)
         }
+    private val dbImportLauncher =
+        registerForActivityResult(OpenDocument()) { uri ->
+            settingsManager.importDb(uri)
+        }
 
     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: 
String?) {
         setPreferencesFromResource(R.xml.settings_main, rootKey)
@@ -81,6 +88,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
         prefWithdrawTest = findPreference("pref_testkudos")!!
         prefLogcat = findPreference("pref_logcat")!!
         prefExportDb = findPreference("pref_export_db")!!
+        prefImportDb = findPreference("pref_import_db")!!
         prefVersionApp = findPreference("pref_version_app")!!
         prefVersionCore = findPreference("pref_version_core")!!
         prefVersionExchange = 
findPreference("pref_version_protocol_exchange")!!
@@ -127,10 +135,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
             true
         }
         prefExportDb.setOnPreferenceClickListener {
-            
dbExportLauncher.launch("taler-wallet-db-${currentTimeMillis()}.sql")
+            
dbExportLauncher.launch("taler-wallet-db-${currentTimeMillis()}.json")
+            true
+        }
+        prefImportDb.setOnPreferenceClickListener {
+            showImportDialog()
             true
         }
-
         prefTest.setOnPreferenceClickListener {
             model.runIntegrationTest()
             true
@@ -141,15 +152,27 @@ class SettingsFragment : PreferenceFragmentCompat() {
         }
     }
 
+    private fun showImportDialog() {
+        MaterialAlertDialogBuilder(requireContext(), 
R.style.MaterialAlertDialog_Material3)
+            .setMessage(R.string.settings_dialog_import_message)
+            .setNegativeButton(R.string.import_db) { _, _ ->
+                dbImportLauncher.launch(arrayOf("application/json"))
+            }
+            .setPositiveButton(R.string.cancel) { _, _ ->
+                Snackbar.make(requireView(), 
getString(R.string.settings_alert_import_canceled), LENGTH_SHORT).show()
+            }
+            .show()
+    }
+
     private fun showResetDialog() {
         MaterialAlertDialogBuilder(requireContext(), 
R.style.MaterialAlertDialog_Material3)
-            .setMessage("Do you really want to reset the wallet and lose all 
coins and purchases?")
-            .setPositiveButton("Reset") { _, _ ->
+            .setMessage(R.string.settings_dialog_reset_message)
+            .setNegativeButton(R.string.reset) { _, _ ->
                 model.dangerouslyReset()
-                Snackbar.make(requireView(), "Wallet has been reset", 
LENGTH_SHORT).show()
+                Snackbar.make(requireView(), 
getString(R.string.settings_alert_reset_done), LENGTH_SHORT).show()
             }
-            .setNegativeButton("Cancel") { _, _ ->
-                Snackbar.make(requireView(), "Reset cancelled", 
LENGTH_SHORT).show()
+            .setPositiveButton(R.string.cancel) { _, _ ->
+                Snackbar.make(requireView(), 
getString(R.string.settings_alert_reset_canceled), LENGTH_SHORT).show()
             }
             .show()
     }
diff --git a/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt 
b/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt
index 349c7b1..0b4cbe9 100644
--- a/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt
@@ -25,14 +25,19 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
 import net.taler.wallet.R
-import net.taler.wallet.backend.WALLET_DB
+import net.taler.wallet.backend.WalletBackendApi
+import net.taler.wallet.backend.WalletResponse.Error
+import net.taler.wallet.backend.WalletResponse.Success
+import org.json.JSONObject
 
 class SettingsManager(
     private val context: Context,
+    private val api: WalletBackendApi,
     private val scope: CoroutineScope,
 ) {
-
     fun exportLogcat(uri: Uri?) {
         if (uri == null) {
             onLogExportError()
@@ -65,20 +70,76 @@ class SettingsManager(
             onDbExportError()
             return
         }
+
         scope.launch(Dispatchers.IO) {
-            try {
-                context.contentResolver.openOutputStream(uri, "wt")?.use { 
outputStream ->
-                    context.openFileInput(WALLET_DB).use { inputStream ->
-                        inputStream.copyTo(outputStream)
+            when (val response = api.rawRequest("exportDb")) {
+                is Success -> {
+                    try {
+                        context.contentResolver.openOutputStream(uri, 
"wt")?.use { outputStream ->
+                            val data = Json.encodeToString(response.result)
+                            val writer = outputStream.bufferedWriter()
+                            writer.write(data)
+                            writer.close()
+                        }
+                    } catch(e: Exception) {
+                        Log.e(SettingsManager::class.simpleName, "Error 
exporting db: ", e)
+                        withContext(Dispatchers.Main) {
+                            onDbExportError()
+                        }
+                        return@launch
                     }
-                } ?: onDbExportError()
-            } catch (e: Exception) {
-                Log.e(SettingsManager::class.simpleName, "Error exporting db: 
", e)
-                onDbExportError()
-                return@launch
+
+                    withContext(Dispatchers.Main) {
+                        Toast.makeText(context, 
R.string.settings_db_export_success, LENGTH_LONG).show()
+                    }
+                }
+                is Error -> {
+                    Log.e(SettingsManager::class.simpleName, "Error exporting 
db: ${response.error}")
+                    withContext(Dispatchers.Main) {
+                        onDbExportError()
+                    }
+                    return@launch
+                }
             }
-            withContext(Dispatchers.Main) {
-                Toast.makeText(context, R.string.settings_db_export_success, 
LENGTH_LONG).show()
+        }
+    }
+
+    fun importDb(uri: Uri?) {
+        if (uri == null) {
+            onDbImportError()
+            return
+        }
+
+        scope.launch(Dispatchers.IO) {
+            context.contentResolver.openInputStream(uri)?.use {  inputStream ->
+                try {
+                    val reader = inputStream.bufferedReader()
+                    val strData = reader.readText()
+                    reader.close()
+                    val jsonData = JSONObject(strData)
+                    when (val response = api.rawRequest("importDb") {
+                        put("dump", jsonData)
+                    }) {
+                        is Success -> {
+                            withContext(Dispatchers.Main) {
+                                Toast.makeText(context, 
R.string.settings_db_import_success, LENGTH_LONG).show()
+                            }
+                        }
+                        is Error -> {
+                            Log.e(SettingsManager::class.simpleName, "Error 
importing db: ${response.error}")
+                            withContext(Dispatchers.Main) {
+                                onDbImportError()
+                            }
+                            return@launch
+                        }
+                    }
+                } catch (e: Exception) {
+                    Log.e(SettingsManager::class.simpleName, "Error importing 
db: ", e)
+                    withContext(Dispatchers.Main) {
+                        onDbImportError()
+                    }
+                    return@launch
+                }
             }
         }
     }
@@ -87,4 +148,8 @@ class SettingsManager(
         Toast.makeText(context, R.string.settings_db_export_error, 
LENGTH_LONG).show()
     }
 
+    private fun onDbImportError() {
+        Toast.makeText(context, R.string.settings_db_import_error, 
LENGTH_LONG).show()
+    }
+
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
index 18480e1..c9ae889 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
@@ -39,6 +39,8 @@ import 
net.taler.wallet.transactions.TransactionAdapter.TransactionViewHolder
 import net.taler.wallet.transactions.TransactionMajorState.Aborted
 import net.taler.wallet.transactions.TransactionMajorState.Failed
 import net.taler.wallet.transactions.TransactionMajorState.Pending
+import net.taler.wallet.transactions.TransactionMinorState.BankConfirmTransfer
+import net.taler.wallet.transactions.TransactionMinorState.KycRequired
 
 internal class TransactionAdapter(
     private val listener: OnTransactionClickListener,
@@ -112,6 +114,14 @@ internal class TransactionAdapter(
 
         private fun bindExtraInfo(transaction: Transaction) {
             when {
+                // Goes first so it always shows errors when present
+                transaction.error != null -> {
+                    extraInfoView.text =
+                        context.getString(R.string.payment_error, 
transaction.error!!.userFacingMsg)
+                    extraInfoView.setTextColor(red)
+                    extraInfoView.visibility = VISIBLE
+                }
+
                 transaction.txState.major == Aborted -> {
                     extraInfoView.setText(R.string.payment_aborted)
                     extraInfoView.setTextColor(red)
@@ -124,11 +134,18 @@ internal class TransactionAdapter(
                     extraInfoView.visibility = VISIBLE
                 }
 
-                transaction.error != null -> {
-                    extraInfoView.text =
-                        context.getString(R.string.payment_error, 
transaction.error!!.userFacingMsg)
-                    extraInfoView.setTextColor(red)
-                    extraInfoView.visibility = VISIBLE
+                transaction.txState.major == Pending -> when 
(transaction.txState.minor) {
+                    BankConfirmTransfer -> {
+                        
extraInfoView.setText(R.string.withdraw_waiting_confirm)
+                        extraInfoView.setTextColor(amountColor)
+                        extraInfoView.visibility = VISIBLE
+                    }
+                    KycRequired -> {
+                        extraInfoView.setText(R.string.transaction_action_kyc)
+                        extraInfoView.setTextColor(amountColor)
+                        extraInfoView.visibility = VISIBLE
+                    }
+                    else -> extraInfoView.visibility = GONE
                 }
 
                 transaction is TransactionWithdrawal && !transaction.confirmed 
-> {
diff --git 
a/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
 
b/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
index 79cfc5e..378e283 100644
--- 
a/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
+++ 
b/wallet/src/main/java/net/taler/wallet/withdraw/TransactionWithdrawalComposable.kt
@@ -86,11 +86,14 @@ fun TransactionWithdrawalComposable(
             amount = t.amountRaw,
             amountType = AmountType.Neutral,
         )
-        TransactionAmountComposable(
-            label = stringResource(id = R.string.withdraw_fees),
-            amount = t.amountRaw - t.amountEffective,
-            amountType = AmountType.Negative,
-        )
+        val fee = t.amountRaw - t.amountEffective
+        if (!fee.isZero()) {
+            TransactionAmountComposable(
+                label = stringResource(id = R.string.withdraw_fees),
+                amount = fee,
+                amountType = AmountType.Negative,
+            )
+        }
         TransactionInfoComposable(
             label = stringResource(id = R.string.withdraw_exchange),
             info = cleanExchange(t.exchangeBaseUrl),
diff --git a/wallet/src/main/res/layout/list_item_age.xml 
b/wallet/src/main/res/drawable/ic_archive.xml
similarity index 56%
copy from wallet/src/main/res/layout/list_item_age.xml
copy to wallet/src/main/res/drawable/ic_archive.xml
index 2d3a6e5..58a032c 100644
--- a/wallet/src/main/res/layout/list_item_age.xml
+++ b/wallet/src/main/res/drawable/ic_archive.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?><!--
+<!--
   ~ This file is part of GNU Taler
   ~ (C) 2023 Taler Systems S.A.
   ~
@@ -14,13 +14,8 @@
   ~ GNU Taler; see the file COPYING.  If not, see 
<http://www.gnu.org/licenses/>
   -->
 
-<TextView xmlns:android="http://schemas.android.com/apk/res/android";
-    android:id="@android:id/text1"
-    style="?android:attr/spinnerItemStyle"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:ellipsize="marquee"
-    android:padding="8dp"
-    android:singleLine="true"
-    android:textAlignment="inherit"
-    android:textSize="20sp" />
+<vector android:height="24dp" android:tint="?attr/colorControlNormal"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" 
xmlns:android="http://schemas.android.com/apk/res/android";>
+    <path android:fillColor="@android:color/white" 
android:pathData="M20.54,5.23l-1.39,-1.68C18.88,3.21 18.47,3 18,3H6c-0.47,0 
-0.88,0.21 -1.16,0.55L3.46,5.23C3.17,5.57 3,6.02 3,6.5V19c0,1.1 0.9,2 
2,2h14c1.1,0 2,-0.9 2,-2V6.5c0,-0.48 -0.17,-0.93 
-0.46,-1.27zM12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5zM5.12,5l0.81,-1h12l0.94,1H5.12z"/>
+</vector>
diff --git a/wallet/src/main/res/values/strings.xml 
b/wallet/src/main/res/values/strings.xml
index 3b05ae9..09feee6 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -59,6 +59,8 @@ GNU Taler is immune against many types of fraud, such as 
phishing of credit card
     <string name="currency">Currency</string>
     <!-- The count should be mirrored in RTL languages -->
     <string name="char_count">%1$d/%2$d</string>
+    <string name="import_db">Import</string>
+    <string name="reset">Reset</string>
 
     <string name="offline">Operation requires internet access. Please ensure 
your internet connection works and try again.</string>
     <string name="offline_banner">No internet access</string>
@@ -257,10 +259,14 @@ GNU Taler is immune against many types of fraud, such as 
phishing of credit card
     <string name="settings_logcat_summary">Save internal log</string>
     <string name="settings_logcat_error">Error exporting log</string>
     <string name="settings_logcat_success">Log exported to file</string>
-    <string name="settings_db_export">Database</string>
+    <string name="settings_db_export">Export database</string>
     <string name="settings_db_export_summary">Save internal database</string>
+    <string name="settings_db_import">Import database</string>
+    <string name="settings_db_import_summary">Restore database from 
file</string>
     <string name="settings_db_export_error">Error exporting database</string>
+    <string name="settings_db_import_error">Error importing database</string>
     <string name="settings_db_export_success">Database exported to 
file</string>
+    <string name="settings_db_import_success">Database imported from 
file</string>
     <string name="settings_version_app">App Version</string>
     <string name="settings_version_core">Wallet Core Version</string>
     <string name="settings_version_protocol_exchange">Supported Exchange 
Versions</string>
@@ -271,6 +277,12 @@ GNU Taler is immune against many types of fraud, such as 
phishing of credit card
     <string name="settings_reset">Reset Wallet (dangerous!)</string>
     <string name="settings_reset_summary">Throws away your money</string>
 
+    <string name="settings_dialog_reset_message">Do you really want to reset 
the wallet and lose all coins and purchases?</string>
+    <string name="settings_dialog_import_message">This operation will 
overwrite your existing database. Do you want to continue?</string>
+    <string name="settings_alert_reset_done">Wallet has been reset</string>
+    <string name="settings_alert_reset_canceled">Reset cancelled</string>
+    <string name="settings_alert_import_canceled">Import cancelled</string>
+
     <string name="refund_title">Refund</string>
     <string name="refund_error">Error processing refund</string>
     <string name="refund_success">Refund received!</string>
diff --git a/wallet/src/main/res/xml/settings_main.xml 
b/wallet/src/main/res/xml/settings_main.xml
index 3a6d991..739e119 100644
--- a/wallet/src/main/res/xml/settings_main.xml
+++ b/wallet/src/main/res/xml/settings_main.xml
@@ -55,6 +55,14 @@
         app:title="@string/settings_db_export"
         tools:isPreferenceVisible="true" />
 
+    <Preference
+        app:icon="@drawable/ic_archive"
+        app:isPreferenceVisible="false"
+        app:key="pref_import_db"
+        app:summary="@string/settings_db_import_summary"
+        app:title="@string/settings_db_import"
+        tools:isPreferenceVisible="true" />
+
     <Preference
         app:icon="@drawable/ic_account_balance_wallet"
         app:isPreferenceVisible="false"

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]