diff --git a/wallet/build.gradle b/wallet/build.gradle
index b73a1674b2..e729b13092 100644
--- a/wallet/build.gradle
+++ b/wallet/build.gradle
@@ -51,7 +51,7 @@ dependencies {
implementation 'com.github.tony19:logback-android-core:1.1.1-6'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation 'com.tbuonomo.andrui:viewpagerdotsindicator:4.1.2'
- implementation 'com.sambarboza:orbitview:0.1.4'
+ implementation 'com.sambarboza:orbitview:0.2.0'
implementation project(path: ':common')
implementation project(path: ':ui-redesign')
diff --git a/wallet/res/drawable-xhdpi/identity_processing_0.png b/wallet/res/drawable-xhdpi/identity_processing_0.png
index d76e3695cb..2794f5f8a8 100644
Binary files a/wallet/res/drawable-xhdpi/identity_processing_0.png and b/wallet/res/drawable-xhdpi/identity_processing_0.png differ
diff --git a/wallet/res/drawable-xhdpi/identity_processing_1.png b/wallet/res/drawable-xhdpi/identity_processing_1.png
index 7985d324de..d5c474572f 100644
Binary files a/wallet/res/drawable-xhdpi/identity_processing_1.png and b/wallet/res/drawable-xhdpi/identity_processing_1.png differ
diff --git a/wallet/res/drawable-xhdpi/identity_processing_2.png b/wallet/res/drawable-xhdpi/identity_processing_2.png
index 43a032cbcb..57990ae148 100644
Binary files a/wallet/res/drawable-xhdpi/identity_processing_2.png and b/wallet/res/drawable-xhdpi/identity_processing_2.png differ
diff --git a/wallet/res/drawable-xhdpi/identity_processing_3.png b/wallet/res/drawable-xhdpi/identity_processing_3.png
index 93f6f1fe76..8165c844c6 100644
Binary files a/wallet/res/drawable-xhdpi/identity_processing_3.png and b/wallet/res/drawable-xhdpi/identity_processing_3.png differ
diff --git a/wallet/res/drawable-xhdpi/identity_processing_4.png b/wallet/res/drawable-xhdpi/identity_processing_4.png
index af35808d65..1b8b3dbd91 100644
Binary files a/wallet/res/drawable-xhdpi/identity_processing_4.png and b/wallet/res/drawable-xhdpi/identity_processing_4.png differ
diff --git a/wallet/res/drawable-xhdpi/identity_processing_5.png b/wallet/res/drawable-xhdpi/identity_processing_5.png
index 62bebaef08..b923fee7e3 100644
Binary files a/wallet/res/drawable-xhdpi/identity_processing_5.png and b/wallet/res/drawable-xhdpi/identity_processing_5.png differ
diff --git a/wallet/res/drawable-xhdpi/identity_processing_6.png b/wallet/res/drawable-xhdpi/identity_processing_6.png
index 74b20d8255..45fc77ba60 100644
Binary files a/wallet/res/drawable-xhdpi/identity_processing_6.png and b/wallet/res/drawable-xhdpi/identity_processing_6.png differ
diff --git a/wallet/res/drawable-xhdpi/identity_processing_7.png b/wallet/res/drawable-xhdpi/identity_processing_7.png
deleted file mode 100644
index 0688c70b54..0000000000
Binary files a/wallet/res/drawable-xhdpi/identity_processing_7.png and /dev/null differ
diff --git a/wallet/res/drawable/ic_circle_forward_arrow.xml b/wallet/res/drawable/ic_circle_forward_arrow.xml
new file mode 100644
index 0000000000..0d472e4484
--- /dev/null
+++ b/wallet/res/drawable/ic_circle_forward_arrow.xml
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/wallet/res/drawable/identity_complete_icon.xml b/wallet/res/drawable/identity_complete_icon.xml
new file mode 100644
index 0000000000..93c1d27c26
--- /dev/null
+++ b/wallet/res/drawable/identity_complete_icon.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wallet/res/drawable/identity_processing.xml b/wallet/res/drawable/identity_processing.xml
index 3c956b3f0a..39a51beb93 100644
--- a/wallet/res/drawable/identity_processing.xml
+++ b/wallet/res/drawable/identity_processing.xml
@@ -1,13 +1,28 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wallet/res/layout/create_username.xml b/wallet/res/layout/create_username.xml
index 48e70d8c86..e798ab764d 100644
--- a/wallet/res/layout/create_username.xml
+++ b/wallet/res/layout/create_username.xml
@@ -9,60 +9,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:background="@color/bg_less_bright"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ app:layout_constraintTop_toBottomOf="@id/header">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wallet/res/layout/identity_creation_state.xml b/wallet/res/layout/identity_creation_state.xml
new file mode 100644
index 0000000000..4af7abdc88
--- /dev/null
+++ b/wallet/res/layout/identity_creation_state.xml
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wallet/res/layout/users_orbit.xml b/wallet/res/layout/users_orbit.xml
index 7b53c7e52f..f52bcca9bd 100644
--- a/wallet/res/layout/users_orbit.xml
+++ b/wallet/res/layout/users_orbit.xml
@@ -1,6 +1,7 @@
+ app:toAngle="135">
+
+
+
+
@@ -38,11 +45,17 @@
android:layout_height="36dp"
android:clipToPadding="false"
app:animStartDelay="600"
- app:drawable="@drawable/user2"
app:fromAngle="55"
app:interpolator="decelerate"
app:orbitDuration="350"
- app:toAngle="110" />
+ app:toAngle="110">
+
+
+
+
@@ -58,11 +71,17 @@
android:layout_height="36dp"
android:clipToPadding="false"
app:animStartDelay="600"
- app:drawable="@drawable/user3"
app:fromAngle="65"
app:interpolator="decelerate"
app:orbitDuration="400"
- app:toAngle="130" />
+ app:toAngle="130">
+
+
+
+
@@ -78,22 +97,77 @@
android:layout_height="36dp"
android:clipToPadding="false"
app:animStartDelay="600"
- app:drawable="@drawable/user4"
app:fromAngle="80"
app:interpolator="decelerate"
app:orbitDuration="450"
- app:toAngle="160" />
+ app:toAngle="160">
+
+
+
+
+ app:toAngle="115"
+ tools:visibility="gone">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wallet/res/values/strings-extra.xml b/wallet/res/values/strings-extra.xml
index dacd0a8105..49c969de73 100644
--- a/wallet/res/values/strings-extra.xml
+++ b/wallet/res/values/strings-extra.xml
@@ -1,5 +1,5 @@
-
+
Create a New Wallet
Restore Wallet From Recovery Phrase
@@ -333,5 +333,13 @@
Your username %s is being created on the Dash Network
Let me know when it\'s done
+ Upgrading to DashPay
+ (1/3) Processing Payment
+ (2/3) Creating ID
+ (3/3) Registering Username
+ Hello %s,
+ Your DashPay Username is ready to use
+
+ Your username %s has been successfully created on the Dash Network
\ No newline at end of file
diff --git a/wallet/schemas/de.schildbach.wallet.AppDatabase/3.json b/wallet/schemas/de.schildbach.wallet.AppDatabase/3.json
new file mode 100644
index 0000000000..1f16c7dcea
--- /dev/null
+++ b/wallet/schemas/de.schildbach.wallet.AppDatabase/3.json
@@ -0,0 +1,134 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 3,
+ "identityHash": "27b793294fd8caf49fe7757c3c19fc9d",
+ "entities": [
+ {
+ "tableName": "exchange_rates",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`currencyCode` TEXT NOT NULL, `rate` TEXT, PRIMARY KEY(`currencyCode`))",
+ "fields": [
+ {
+ "fieldPath": "currencyCode",
+ "columnName": "currencyCode",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "rate",
+ "columnName": "rate",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "currencyCode"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "blockchain_state",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `bestChainDate` INTEGER, `bestChainHeight` INTEGER NOT NULL, `replaying` INTEGER NOT NULL, `impediments` TEXT NOT NULL, `chainlockHeight` INTEGER NOT NULL, `mnlistHeight` INTEGER NOT NULL, `percentageSync` INTEGER NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "bestChainDate",
+ "columnName": "bestChainDate",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "bestChainHeight",
+ "columnName": "bestChainHeight",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "replaying",
+ "columnName": "replaying",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "impediments",
+ "columnName": "impediments",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "chainlockHeight",
+ "columnName": "chainlockHeight",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "mnlistHeight",
+ "columnName": "mnlistHeight",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "percentageSync",
+ "columnName": "percentageSync",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "identity_creation_state",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `state` INTEGER NOT NULL, `username` TEXT NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "username",
+ "columnName": "username",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '27b793294fd8caf49fe7757c3c19fc9d')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/AppDatabase.java b/wallet/src/de/schildbach/wallet/AppDatabase.java
index 91e4c3d8c3..28b352fae0 100644
--- a/wallet/src/de/schildbach/wallet/AppDatabase.java
+++ b/wallet/src/de/schildbach/wallet/AppDatabase.java
@@ -7,6 +7,8 @@
import de.schildbach.wallet.data.BlockchainState;
import de.schildbach.wallet.data.BlockchainStateDao;
+import de.schildbach.wallet.data.IdentityCreationState;
+import de.schildbach.wallet.data.IdentityCreationStateDao;
import de.schildbach.wallet.data.RoomConverters;
import de.schildbach.wallet.rates.ExchangeRate;
import de.schildbach.wallet.rates.ExchangeRatesDao;
@@ -14,7 +16,7 @@
/**
* @author Samuel Barbosa
*/
-@Database(entities = {ExchangeRate.class, BlockchainState.class}, version = 2)
+@Database(entities = {ExchangeRate.class, BlockchainState.class, IdentityCreationState.class}, version = 3)
@TypeConverters({RoomConverters.class})
public abstract class AppDatabase extends RoomDatabase {
@@ -22,6 +24,7 @@ public abstract class AppDatabase extends RoomDatabase {
public abstract ExchangeRatesDao exchangeRatesDao();
public abstract BlockchainStateDao blockchainStateDao();
+ public abstract IdentityCreationStateDao identityCreationStateDao();
public static AppDatabase getAppDatabase() {
if (instance == null) {
diff --git a/wallet/src/de/schildbach/wallet/data/IdentityCreationState.kt b/wallet/src/de/schildbach/wallet/data/IdentityCreationState.kt
new file mode 100644
index 0000000000..ee408755be
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/data/IdentityCreationState.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020 Dash Core Group.
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see .
+ */
+
+package de.schildbach.wallet.data
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity(tableName = "identity_creation_state")
+class IdentityCreationState(var state: State, var username: String) {
+
+ @PrimaryKey
+ var id = 1
+ set(value) {
+ field = 1
+ }
+
+ enum class State {
+ PROCESSING_PAYMENT, CREATING_IDENTITY, REGISTERING_USERNAME, DONE
+ }
+
+ fun nextState() {
+ state = when (state) {
+ State.PROCESSING_PAYMENT -> State.CREATING_IDENTITY
+ State.CREATING_IDENTITY -> State.REGISTERING_USERNAME
+ State.REGISTERING_USERNAME -> State.DONE
+ else -> State.PROCESSING_PAYMENT
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/data/IdentityCreationStateDao.kt b/wallet/src/de/schildbach/wallet/data/IdentityCreationStateDao.kt
new file mode 100644
index 0000000000..3a0c6286a3
--- /dev/null
+++ b/wallet/src/de/schildbach/wallet/data/IdentityCreationStateDao.kt
@@ -0,0 +1,18 @@
+package de.schildbach.wallet.data
+
+import androidx.lifecycle.LiveData
+import androidx.room.*
+
+@Dao
+interface IdentityCreationStateDao {
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun insert(identityCreationState: IdentityCreationState)
+
+ @Query("SELECT * FROM identity_creation_state LIMIT 1")
+ fun load(): LiveData
+
+ @Query("DELETE FROM identity_creation_state")
+ fun clear()
+
+}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/data/RoomConverters.kt b/wallet/src/de/schildbach/wallet/data/RoomConverters.kt
index ccfae3f60c..49a737a063 100644
--- a/wallet/src/de/schildbach/wallet/data/RoomConverters.kt
+++ b/wallet/src/de/schildbach/wallet/data/RoomConverters.kt
@@ -33,7 +33,7 @@ class RoomConverters {
}
@TypeConverter
- fun fromImpedimentsEnumSet(value: String?): Set {
+ fun fromImpedimentsString(value: String?): Set {
val impedimentSet = EnumSet.noneOf(BlockchainState.Impediment::class.java)
if (value == null || value.isEmpty()) {
return impedimentSet
@@ -57,4 +57,14 @@ class RoomConverters {
return sb.toString()
}
+ @TypeConverter
+ fun toIdentityCreationState(value: Int): IdentityCreationState.State {
+ return IdentityCreationState.State.values()[value]
+ }
+
+ @TypeConverter
+ fun fromIdentityCreationState(identityCreationState: IdentityCreationState.State): Int {
+ return identityCreationState.ordinal
+ }
+
}
\ No newline at end of file
diff --git a/wallet/src/de/schildbach/wallet/ui/CreateUsernameActivity.kt b/wallet/src/de/schildbach/wallet/ui/CreateUsernameActivity.kt
index f75d3a165c..8ad4546ae2 100644
--- a/wallet/src/de/schildbach/wallet/ui/CreateUsernameActivity.kt
+++ b/wallet/src/de/schildbach/wallet/ui/CreateUsernameActivity.kt
@@ -29,10 +29,14 @@ import android.view.animation.AnimationUtils
import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
+import de.schildbach.wallet.AppDatabase
+import de.schildbach.wallet.data.IdentityCreationState
import de.schildbach.wallet.ui.dashpay.NewAccountConfirmDialog
import de.schildbach.wallet_test.R
import kotlinx.android.synthetic.main.create_username.*
+import kotlinx.android.synthetic.main.users_orbit.*
import org.dash.wallet.common.InteractionAwareActivity
+import java.util.concurrent.Executors
class CreateUsernameActivity : InteractionAwareActivity(), TextWatcher {
@@ -40,6 +44,12 @@ class CreateUsernameActivity : InteractionAwareActivity(), TextWatcher {
private val mediumTypeFace by lazy { ResourcesCompat.getFont(this, R.font.montserrat_medium) }
private val slideInAnimation by lazy { AnimationUtils.loadAnimation(this, R.anim.slide_in_bottom) }
private val fadeOutAnimation by lazy { AnimationUtils.loadAnimation(this, R.anim.fade_out) }
+ private lateinit var completeUsername: String
+
+ companion object {
+ @JvmStatic
+ public val COMPLETE_USERNAME = "complete_username"
+ }
override fun onCreate(savedInstanceState: Bundle?) {
@@ -52,6 +62,37 @@ class CreateUsernameActivity : InteractionAwareActivity(), TextWatcher {
username.addTextChangedListener(this)
register_btn.setOnClickListener { showConfirmationDialog() }
processing_identity_dismiss_btn.setOnClickListener { finish() }
+
+ val intentUsername = intent?.extras?.getString(COMPLETE_USERNAME)
+ if (intentUsername != null) {
+ this.completeUsername = intentUsername
+ showCompleteState()
+ }
+
+ val confirmTransactionSharedViewModel = ViewModelProviders.of(this)
+ .get(SingleActionSharedViewModel::class.java)
+ confirmTransactionSharedViewModel.clickConfirmButtonEvent.observe(this, Observer {
+ showProcessingState()
+ })
+ }
+
+ private fun showCompleteState() {
+ registration_content.visibility = View.GONE
+ processing_identity.visibility = View.GONE
+ choose_username_title.visibility = View.GONE
+ placeholder_user_icon.visibility = View.GONE
+ identity_complete.visibility = View.VISIBLE
+ dashpay_user_icon.visibility = View.VISIBLE
+ username_1st_letter.text = completeUsername[0].toString()
+
+ val text = getString(R.string.identity_complete_message, completeUsername)
+
+ val spannableContent = SpannableString(text)
+ val start = text.indexOf(completeUsername)
+ val end = start + completeUsername.length
+ spannableContent.setSpan(StyleSpan(Typeface.BOLD), start, end, 0)
+ identity_complete_text.text = spannableContent
+ identity_complete_button.setOnClickListener { finish() }
}
private fun validateUsernameSize(uname: String): Boolean {
@@ -110,17 +151,18 @@ class CreateUsernameActivity : InteractionAwareActivity(), TextWatcher {
val end = start + username.length
spannableContent.setSpan(StyleSpan(Typeface.BOLD), start, end, 0)
processing_identity_message.text = spannableContent
+
+ Executors.newSingleThreadExecutor().execute {
+ val identityCreationState = IdentityCreationState(IdentityCreationState
+ .State.PROCESSING_PAYMENT, username)
+ AppDatabase.getAppDatabase().identityCreationStateDao().insert(identityCreationState)
+ }
}
private fun showConfirmationDialog() {
val dialog = NewAccountConfirmDialog.createDialog()
dialog.show(supportFragmentManager, "NewAccountConfirmDialog")
- val confirmTransactionSharedViewModel = ViewModelProviders.of(this)
- .get(SingleActionSharedViewModel::class.java)
- confirmTransactionSharedViewModel.clickConfirmButtonEvent.observe(this, Observer {
- showProcessingState()
- })
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
diff --git a/wallet/src/de/schildbach/wallet/ui/TransactionsAdapter.java b/wallet/src/de/schildbach/wallet/ui/TransactionsAdapter.java
index de2f12e280..699c7d1fd4 100644
--- a/wallet/src/de/schildbach/wallet/ui/TransactionsAdapter.java
+++ b/wallet/src/de/schildbach/wallet/ui/TransactionsAdapter.java
@@ -17,52 +17,51 @@
package de.schildbach.wallet.ui;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.drawable.AnimationDrawable;
+import android.text.format.DateUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
-import javax.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.cardview.widget.CardView;
+import androidx.recyclerview.widget.RecyclerView;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Sha256Hash;
-import org.bitcoinj.core.StoredBlock;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
-import org.bitcoinj.core.TransactionConfidence.ConfidenceType;
import org.bitcoinj.utils.ExchangeRate;
import org.bitcoinj.utils.MonetaryFormat;
import org.bitcoinj.wallet.Wallet;
-import org.bitcoinj.wallet.ZeroConfCoinSelector;
import org.dash.wallet.common.ui.CurrencyTextView;
-import org.dash.wallet.common.ui.Formats;
import org.dash.wallet.common.util.GenericUtils;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+
+import javax.annotation.Nullable;
+
+import de.schildbach.wallet.AppDatabase;
import de.schildbach.wallet.Constants;
-import de.schildbach.wallet.WalletApplication;
import de.schildbach.wallet.data.AddressBookProvider;
-
-import de.schildbach.wallet.util.FiatExtensionsKt;
+import de.schildbach.wallet.data.IdentityCreationState;
import de.schildbach.wallet.util.TransactionUtil;
import de.schildbach.wallet.util.WalletUtils;
import de.schildbach.wallet_test.R;
-import android.content.Context;
-import android.content.res.Resources;
-
-import androidx.cardview.widget.CardView;
-import androidx.recyclerview.widget.RecyclerView;
-
-import android.text.format.DateUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
/**
* @author Andreas Schildbach
*/
@@ -95,9 +94,13 @@ public class TransactionsAdapter extends RecyclerView.Adapter transactionCache = new HashMap();
+ //Temporary field while IdentityCreationTx (or whatever we call it) is not integrated yet.
+ private IdentityCreationState identityCreationState;
+
private static class TransactionCacheEntry {
private final Coin value;
private final boolean sent;
@@ -173,12 +176,6 @@ public void replace(final Collection transactions) {
notifyDataSetChanged();
}
- public void setSelectedItemId(final long itemId) {
- selectedItemId = itemId;
-
- notifyDataSetChanged();
- }
-
public void clearCacheAndNotifyDataSetChanged() {
transactionCache.clear();
@@ -189,11 +186,11 @@ public void clearCacheAndNotifyDataSetChanged() {
public int getItemCount() {
int count = transactions.size();
- return count;
- }
+ if (identityCreationState != null) {
+ count += 1;
+ }
- public int getTransactionsCount() {
- return transactions.size();
+ return count;
}
@Override
@@ -201,21 +198,30 @@ public long getItemId(int position) {
if (position == RecyclerView.NO_POSITION)
return RecyclerView.NO_ID;
- return WalletUtils.longHash(transactions.get(position).getHash());
+ if (identityCreationState != null) {
+ if (position == 0) {
+ return identityCreationState.getId();
+ } else {
+ return WalletUtils.longHash(transactions.get(position - 1).getHash());
+ }
+ } else {
+ return WalletUtils.longHash(transactions.get(position).getHash());
+ }
}
@Override
public int getItemViewType(final int position) {
+ if (identityCreationState != null && position == 0) {
+ return VIEW_TYPE_PROCESSING_IDENTITY;
+ }
return VIEW_TYPE_TRANSACTION;
}
- public RecyclerView.ViewHolder createTransactionViewHolder(final ViewGroup parent) {
- return createViewHolder(parent, VIEW_TYPE_TRANSACTION);
- }
-
@Override
public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
- if (viewType == VIEW_TYPE_TRANSACTION) {
+ if (viewType == VIEW_TYPE_PROCESSING_IDENTITY) {
+ return new ProcessingIdentityViewHolder(inflater.inflate(R.layout.identity_creation_state, parent, false));
+ } else if (viewType == VIEW_TYPE_TRANSACTION) {
return new TransactionViewHolder(inflater.inflate(R.layout.transaction_row, parent, false));
} else {
throw new IllegalStateException("unknown type: " + viewType);
@@ -230,7 +236,12 @@ public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int pos
final long itemId = getItemId(position);
transactionHolder.itemView.setActivated(itemId == selectedItemId);
- final Transaction tx = transactions.get(position);
+ Transaction tx;
+ if (identityCreationState != null) {
+ tx = transactions.get(position - 1);
+ } else {
+ tx = transactions.get(position);
+ }
transactionHolder.bind(tx);
transactionHolder.itemView.setOnClickListener(new View.OnClickListener() {
@@ -242,6 +253,8 @@ public void onClick(final View v) {
}
}
});
+ } else if (holder instanceof ProcessingIdentityViewHolder) {
+ ((ProcessingIdentityViewHolder) holder).bind(identityCreationState);
}
}
@@ -251,9 +264,78 @@ public void setShowTransactionRowMenu(boolean showTransactionRowMenu) {
public interface OnClickListener {
void onTransactionMenuClick(View view, Transaction tx);
+
void onTransactionRowClicked(Transaction tx);
}
+ private class ProcessingIdentityViewHolder extends RecyclerView.ViewHolder {
+
+ private ImageView animatedIcon;
+ private TextView title;
+ private TextView subTitle;
+ private ProgressBar progress;
+ private ImageView forwardIcon;
+
+ public ProcessingIdentityViewHolder(@NonNull View itemView) {
+ super(itemView);
+ animatedIcon = itemView.findViewById(R.id.processing_animated_icon);
+ title = itemView.findViewById(R.id.processing_title);
+ subTitle = itemView.findViewById(R.id.processing_subtitle);
+ progress = itemView.findViewById(R.id.processing_progress);
+ forwardIcon = itemView.findViewById(R.id.processing_forward_arrow);
+
+ ((AnimationDrawable) animatedIcon.getDrawable()).start();
+ itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (identityCreationState.getState() == IdentityCreationState.State.DONE) {
+ Intent intent = new Intent(v.getContext(), CreateUsernameActivity.class);
+ intent.putExtra(CreateUsernameActivity.Companion.getCOMPLETE_USERNAME(),
+ identityCreationState.getUsername());
+ v.getContext().startActivity(intent);
+ } else {
+ Executors.newSingleThreadExecutor().execute(new Runnable() {
+ @Override
+ public void run() {
+ identityCreationState.nextState();
+ AppDatabase.getAppDatabase()
+ .identityCreationStateDao().insert(identityCreationState);
+ }
+ });
+ }
+ }
+ });
+ }
+
+ public void bind(IdentityCreationState identityCreationState) {
+ switch (identityCreationState.getState()) {
+ case PROCESSING_PAYMENT:
+ animatedIcon.setVisibility(View.VISIBLE);
+ forwardIcon.setVisibility(View.GONE);
+ progress.setProgress(25);
+ subTitle.setText(R.string.processing_home_step_1);
+ break;
+ case CREATING_IDENTITY:
+ progress.setProgress(50);
+ subTitle.setText(R.string.processing_home_step_2);
+ break;
+ case REGISTERING_USERNAME:
+ progress.setProgress(75);
+ subTitle.setText(R.string.processing_home_step_3);
+ break;
+ case DONE:
+ animatedIcon.setVisibility(View.GONE);
+ forwardIcon.setVisibility(View.VISIBLE);
+ progress.setProgress(100);
+ title.setText(itemView.getContext().getString(R.string.processing_done_title,
+ identityCreationState.getUsername()));
+ subTitle.setText(R.string.processing_done_subtitle);
+ break;
+ }
+ }
+
+ }
+
private class TransactionViewHolder extends RecyclerView.ViewHolder {
private final TextView primaryStatusView;
private final TextView secondaryStatusView;
@@ -361,10 +443,10 @@ private void bind(final Transaction tx) {
signalView.setTextColor(valueColor);
dashSymbolView.setColorFilter(valueColor);
- if(value.isPositive()) {
+ if (value.isPositive()) {
signalView.setText(String.format("%c", org.dash.wallet.common.Constants.CURRENCY_PLUS_SIGN));
valueView.setAmount(value);
- } else if(value.isNegative()) {
+ } else if (value.isNegative()) {
signalView.setText(String.format("%c", org.dash.wallet.common.Constants.CURRENCY_MINUS_SIGN));
valueView.setAmount(value.negate());
} else {
@@ -372,9 +454,9 @@ private void bind(final Transaction tx) {
}
// fiat value
- if(!value.isZero()) {
+ if (!value.isZero()) {
final ExchangeRate exchangeRate = tx.getExchangeRate();
- if(exchangeRate != null) {
+ if (exchangeRate != null) {
String exchangeCurrencyCode = GenericUtils.currencySymbol(exchangeRate.fiat.currencyCode);
fiatView.setFiatAmount(txCache.value, exchangeRate, Constants.LOCAL_FORMAT,
exchangeCurrencyCode);
@@ -394,16 +476,26 @@ private void bind(final Transaction tx) {
// Show the secondary status:
//
int secondaryStatusId = -1;
- if(confidence.hasErrors())
+ if (confidence.hasErrors())
secondaryStatusId = TransactionUtil.getErrorName(tx);
- else if(!txCache.sent)
+ else if (!txCache.sent)
secondaryStatusId = TransactionUtil.getReceivedStatusString(tx, wallet);
- if(secondaryStatusId != -1)
+ if (secondaryStatusId != -1)
secondaryStatusView.setText(secondaryStatusId);
else secondaryStatusView.setText(null);
secondaryStatusView.setTextColor(secondaryStatusColor);
}
}
+
+ public IdentityCreationState getIdentityCreationState() {
+ return identityCreationState;
+ }
+
+ public void setIdentityCreationState(IdentityCreationState identityCreationState) {
+ this.identityCreationState = identityCreationState;
+ notifyDataSetChanged();
+ }
+
}
diff --git a/wallet/src/de/schildbach/wallet/ui/WalletActivity.java b/wallet/src/de/schildbach/wallet/ui/WalletActivity.java
index 71461d935a..94d98285fc 100644
--- a/wallet/src/de/schildbach/wallet/ui/WalletActivity.java
+++ b/wallet/src/de/schildbach/wallet/ui/WalletActivity.java
@@ -82,6 +82,7 @@
import java.util.Currency;
import java.util.Locale;
import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
import de.schildbach.wallet.AppDatabase;
import de.schildbach.wallet.Constants;
@@ -207,6 +208,15 @@ public void onChanged(de.schildbach.wallet.data.BlockchainState blockchainState)
});
registerOnCoinsSentReceivedListener();
+
+ //TODO: Remove after integration with back-end
+ Executors.newSingleThreadExecutor().execute(new Runnable() {
+ @Override
+ public void run() {
+ //Uncomment line below to clear identity creation state
+ //AppDatabase.getAppDatabase().identityCreationStateDao().clear();
+ }
+ });
}
private void initFingerprintHelper() {
diff --git a/wallet/src/de/schildbach/wallet/ui/WalletTransactionsFragment.java b/wallet/src/de/schildbach/wallet/ui/WalletTransactionsFragment.java
index b342162975..cb6970fa6c 100644
--- a/wallet/src/de/schildbach/wallet/ui/WalletTransactionsFragment.java
+++ b/wallet/src/de/schildbach/wallet/ui/WalletTransactionsFragment.java
@@ -45,6 +45,7 @@
import android.widget.TextView;
import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.AsyncTaskLoader;
import androidx.loader.content.Loader;
@@ -77,9 +78,11 @@
import javax.annotation.Nullable;
+import de.schildbach.wallet.AppDatabase;
import de.schildbach.wallet.Constants;
import de.schildbach.wallet.WalletApplication;
import de.schildbach.wallet.data.AddressBookProvider;
+import de.schildbach.wallet.data.IdentityCreationState;
import de.schildbach.wallet.util.BitmapFragment;
import de.schildbach.wallet.util.CrashReporter;
import de.schildbach.wallet.util.Qr;
@@ -193,7 +196,7 @@ else if (position == parent.getAdapter().getItemCount() - 1)
}
});
- ArrayAdapter adapter = ArrayAdapter.createFromResource(filterSpinner.getContext(), R.array.history_filter, R.layout.custom_spinner_item);
+ final ArrayAdapter adapter = ArrayAdapter.createFromResource(filterSpinner.getContext(), R.array.history_filter, R.layout.custom_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
filterSpinner.setAdapter(adapter);
filterSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@@ -219,6 +222,15 @@ public void onNothingSelected(AdapterView> parent) {
}
});
+ AppDatabase.getAppDatabase().identityCreationStateDao().load().observe(this, new Observer() {
+ @Override
+ public void onChanged(IdentityCreationState identityCreationState) {
+ if (identityCreationState != null) {
+ WalletTransactionsFragment.this.adapter.setIdentityCreationState(identityCreationState);
+ }
+ }
+ });
+
return view;
}