From e7d2719a4daec4efc173084309827c70f423e565 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 31 Oct 2018 13:44:49 -0600 Subject: [PATCH 001/129] Create BitsyDatabase which extends Room and created Assets Entity and Assets Dao to use in the Room db --- .../bitsybitshareswallet/daos/AssetDao.kt | 17 +++++++++ .../daos/BitsyDatabase.kt | 38 +++++++++++++++++++ .../bitsybitshareswallet/models/Asset.kt | 23 +++++++++++ 3 files changed, 78 insertions(+) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/Asset.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt new file mode 100644 index 0000000..2970c84 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt @@ -0,0 +1,17 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.Asset + +@Dao +interface AssetDao { + + @Query("SELECT * FROM assets") + fun getAllAssets(): LiveData> + + @Insert + fun insert(asset: Asset) +} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt new file mode 100644 index 0000000..6c5ab53 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt @@ -0,0 +1,38 @@ +package cy.agorise.bitsybitshareswallet.daos + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase +import cy.agorise.bitsybitshareswallet.models.Asset + +@Database(entities = [Asset::class], version = 1, exportSchema = false) +abstract class BitsyDatabase : RoomDatabase() { + + abstract fun assetDao(): AssetDao + + companion object { + + // To make sure there is always only one instance of the database open + @Volatile + private var INSTANCE: BitsyDatabase? = null + + internal fun getDatabase(context: Context): BitsyDatabase? { + if (INSTANCE == null) { + synchronized(BitsyDatabase::class.java) { + INSTANCE = Room.databaseBuilder( + context.applicationContext, + BitsyDatabase::class.java, "BiTSyWallet.db" + ) + .build() + } + } + + return INSTANCE + } + + fun destroyInstance() { + INSTANCE = null + } + } +} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Asset.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Asset.kt new file mode 100644 index 0000000..e0c03b9 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Asset.kt @@ -0,0 +1,23 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "assets") +data class Asset( + @PrimaryKey + @ColumnInfo(name = "id") val id: String, + @ColumnInfo(name = "symbol") val symbol: String, + @ColumnInfo(name = "precision") val precision: Int, + @ColumnInfo(name = "issuer") val issuer: String, + @ColumnInfo(name = "description") val description: String, + @ColumnInfo(name = "max_supply") val maxSupply: Long, // TODO verify type + @ColumnInfo(name = "market_fee_percent") val marketFeePercent: Float, // TODO verify type + @ColumnInfo(name = "max_market_fee") val maxMarketFee: Float, // TODO verify type + @ColumnInfo(name = "issuer_permissions") val issuerPermissions: Int, + @ColumnInfo(name = "flags") val flags: Int, + @ColumnInfo(name = "asset_type") val assetType: Int, + @ColumnInfo(name = "bit_asset_id") val bitAssetId: String, + @ColumnInfo(name = "holders_count") val holdersCount: Int +) From c0d20e67bd559ce414997ab529ac5996ca16fa8a Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 31 Oct 2018 14:40:17 -0600 Subject: [PATCH 002/129] Created Balance entity and BalanceDao to create the Balances db table with Room --- .../bitsybitshareswallet/daos/BalanceDao.kt | 17 +++++++++++++++++ .../bitsybitshareswallet/daos/BitsyDatabase.kt | 1 + .../bitsybitshareswallet/models/Balance.kt | 12 ++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt new file mode 100644 index 0000000..3e1cf65 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt @@ -0,0 +1,17 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.Balance + +@Dao +interface BalanceDao { + + @Query("SELECT * FROM balances") + fun getAllBalances(): LiveData> + + @Insert + fun insert(balance: Balance) +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt index 6c5ab53..9e68537 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt @@ -10,6 +10,7 @@ import cy.agorise.bitsybitshareswallet.models.Asset abstract class BitsyDatabase : RoomDatabase() { abstract fun assetDao(): AssetDao + abstract fun balanceDao(): BalanceDao companion object { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt new file mode 100644 index 0000000..8bfd802 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt @@ -0,0 +1,12 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity + +@Entity(tableName = "balances", primaryKeys = ["user_id", "asset_id"]) +data class Balance( + @ColumnInfo(name = "user_id") val userId: String, + @ColumnInfo(name = "asset_id") val assetId: String, + @ColumnInfo(name = "asset_amount") val assetAmount: Long, + @ColumnInfo(name = "last_update") val lastUpdate: Long +) \ No newline at end of file From e835e7de8952729b6a3a1239af8b28f1148e2487 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 31 Oct 2018 14:51:23 -0600 Subject: [PATCH 003/129] Created UserAccount entity and UserAccountDao to create the UserAccounts db table with Room --- .../bitsybitshareswallet/daos/BitsyDatabase.kt | 1 + .../bitsybitshareswallet/daos/UserAccountDao.kt | 17 +++++++++++++++++ .../bitsybitshareswallet/models/UserAccount.kt | 13 +++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt index 9e68537..02c0a2f 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt @@ -11,6 +11,7 @@ abstract class BitsyDatabase : RoomDatabase() { abstract fun assetDao(): AssetDao abstract fun balanceDao(): BalanceDao + abstract fun userAccountDao(): UserAccountDao companion object { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt new file mode 100644 index 0000000..9bb78f4 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt @@ -0,0 +1,17 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.UserAccount + +@Dao +interface UserAccountDao { + + @Query("SELECT * FROM user_accounts") + fun getAllUserAccounts(): LiveData> + + @Insert + fun insert(userAccount: UserAccount) +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt new file mode 100644 index 0000000..7ed6aa9 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt @@ -0,0 +1,13 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "user_accounts") +data class UserAccount ( + @PrimaryKey + @ColumnInfo(name = "id") val id: String, + @ColumnInfo(name = "name") val name: String, + @ColumnInfo(name = "is_ltm") val isLtm: Boolean // Todo verify data type +) \ No newline at end of file From 72e39368aa49115cf99200ce5180487b19546336 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 31 Oct 2018 15:16:22 -0600 Subject: [PATCH 004/129] Created Authority entity and AuthoritiyDao to create the Authorities db table with Room --- .../bitsybitshareswallet/daos/AuthorityDao.kt | 17 +++++++++++++ .../daos/BitsyDatabase.kt | 1 + .../bitsybitshareswallet/models/Authority.kt | 25 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt new file mode 100644 index 0000000..678e6af --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt @@ -0,0 +1,17 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.Authority + +@Dao +interface AuthorityDao { + + @Query("SELECT * FROM authorities") + fun getAllAuthorities(): LiveData> + + @Insert + fun insert(authority: Authority) +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt index 02c0a2f..b1dfa75 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt @@ -12,6 +12,7 @@ abstract class BitsyDatabase : RoomDatabase() { abstract fun assetDao(): AssetDao abstract fun balanceDao(): BalanceDao abstract fun userAccountDao(): UserAccountDao + abstract fun authorityDao(): AuthorityDao companion object { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt new file mode 100644 index 0000000..38d6c80 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt @@ -0,0 +1,25 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey + +@Entity(tableName = "authorities", foreignKeys = + [ForeignKey( + entity = UserAccount::class, + parentColumns = ["id"], + childColumns = ["user_id"], + onUpdate = ForeignKey.CASCADE, + onDelete = ForeignKey.CASCADE + )] +) +data class Authority ( + @PrimaryKey(autoGenerate = true) + @ColumnInfo(name = "id") val id: Long, + @ColumnInfo(name = "encrypted_brainkey") val encryptedBrainkey: String, + @ColumnInfo(name = "encrypted_sequence_number") val encryptedSequenceNumber: String, // TODO verify data type + @ColumnInfo(name = "encrypted_wif") val encryptedWif: String, + @ColumnInfo(name = "user_id") val userId: String, + @ColumnInfo(name = "authority_type") val authorityType: Int +) \ No newline at end of file From da9e0225cc59166b90e9e7bf6d181c1a542d2643 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 31 Oct 2018 18:51:41 -0600 Subject: [PATCH 005/129] Create Operation, Transfer and Equivalent value Entities for the Room database. --- .../models/EquivalentValue.kt | 29 +++++++++++++++++++ .../bitsybitshareswallet/models/Operation.kt | 14 +++++++++ .../bitsybitshareswallet/models/Transfer.kt | 29 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/EquivalentValue.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/Operation.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/Transfer.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/EquivalentValue.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/EquivalentValue.kt new file mode 100644 index 0000000..19a126d --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/EquivalentValue.kt @@ -0,0 +1,29 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey + +@Entity(tableName = "equivalent_values",foreignKeys = + [ForeignKey( + entity = Transfer::class, + parentColumns = ["operation_id"], + childColumns = ["transfer_id"], + onUpdate = ForeignKey.CASCADE, + onDelete = ForeignKey.CASCADE + ), ForeignKey( + entity = Asset::class, + parentColumns = ["id"], + childColumns = ["asset_id"], + onUpdate = ForeignKey.CASCADE, + onDelete = ForeignKey.CASCADE + )] +) +data class EquivalentValue ( + @PrimaryKey(autoGenerate = true) + @ColumnInfo(name = "id") val id: Long, + @ColumnInfo(name = "transfer_id") val transferId: String, + @ColumnInfo(name = "value") val value: Long, + @ColumnInfo(name = "asset_id") val assetId: String +) \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Operation.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Operation.kt new file mode 100644 index 0000000..765c64f --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Operation.kt @@ -0,0 +1,14 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "operations") +data class Operation ( + @PrimaryKey + @ColumnInfo(name = "id") val id: String, + @ColumnInfo(name = "type") val type: Int, + @ColumnInfo(name = "timestamp") val timestamp: Long, + @ColumnInfo(name = "block_number") val blockNumber: Long +) \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Transfer.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Transfer.kt new file mode 100644 index 0000000..abf1456 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Transfer.kt @@ -0,0 +1,29 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey + +@Entity(tableName = "transfers",foreignKeys = + [ForeignKey( + entity = Operation::class, + parentColumns = ["id"], + childColumns = ["operation_id"], + onUpdate = ForeignKey.CASCADE, + onDelete = ForeignKey.CASCADE + )] +) +data class Transfer ( + @PrimaryKey + @ColumnInfo(name = "operation_id") val operationId: String, + @ColumnInfo(name = "fee_amount") val feeAmount: Long, + @ColumnInfo(name = "fee_asset_id") val feeAssetId: String, + @ColumnInfo(name = "source") val source: String, + @ColumnInfo(name = "destination") val destination: String, + @ColumnInfo(name = "transfer_amount") val transferAmount: Long, + @ColumnInfo(name = "transfer_asset_id") val transferAssetId: String, + @ColumnInfo(name = "memo") val memo: String, + @ColumnInfo(name = "memo_from_key") val memoFromKey: String, + @ColumnInfo(name = "memo_to_key") val memoToKey: String +) \ No newline at end of file From 1c018346aed1163acfa91f47424354aa50412bb1 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 1 Nov 2018 11:19:32 -0600 Subject: [PATCH 006/129] Create UserAccountAuthority entity to establish a N:N relationship between the UserAccount and Authority entities in the database. Also made some structure improvements to all the Entities and Daos already described. --- .../bitsybitshareswallet/daos/AssetDao.kt | 6 ++--- .../bitsybitshareswallet/daos/AuthorityDao.kt | 6 ++--- .../bitsybitshareswallet/daos/BalanceDao.kt | 6 ++--- .../daos/BitsyDatabase.kt | 11 ++++++-- .../daos/UserAccountAuthorityDao.kt | 17 +++++++++++++ .../daos/UserAccountDao.kt | 6 ++--- .../bitsybitshareswallet/models/Authority.kt | 11 +------- .../bitsybitshareswallet/models/Balance.kt | 5 ++-- .../models/EquivalentValue.kt | 8 ++---- .../bitsybitshareswallet/models/Transfer.kt | 12 ++++----- .../models/UserAccount.kt | 3 ++- .../models/UserAccountAuthority.kt | 25 +++++++++++++++++++ 12 files changed, 76 insertions(+), 40 deletions(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccountAuthority.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt index 2970c84..aaac373 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt @@ -9,9 +9,9 @@ import cy.agorise.bitsybitshareswallet.models.Asset @Dao interface AssetDao { - @Query("SELECT * FROM assets") - fun getAllAssets(): LiveData> - @Insert fun insert(asset: Asset) + + @Query("SELECT * FROM assets") + fun getAllAssets(): LiveData> } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt index 678e6af..01e743c 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt @@ -9,9 +9,9 @@ import cy.agorise.bitsybitshareswallet.models.Authority @Dao interface AuthorityDao { - @Query("SELECT * FROM authorities") - fun getAllAuthorities(): LiveData> - @Insert fun insert(authority: Authority) + + @Query("SELECT * FROM authorities") + fun getAllAuthorities(): LiveData> } \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt index 3e1cf65..c646f78 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt @@ -9,9 +9,9 @@ import cy.agorise.bitsybitshareswallet.models.Balance @Dao interface BalanceDao { - @Query("SELECT * FROM balances") - fun getAllBalances(): LiveData> - @Insert fun insert(balance: Balance) + + @Query("SELECT * FROM balances") + fun getAllBalances(): LiveData> } \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt index b1dfa75..b428930 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt @@ -4,15 +4,22 @@ import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase -import cy.agorise.bitsybitshareswallet.models.Asset +import cy.agorise.bitsybitshareswallet.models.* -@Database(entities = [Asset::class], version = 1, exportSchema = false) +@Database(entities = [ + Asset::class, + Balance::class, + UserAccount::class, + Authority::class, + UserAccountAuthority::class + ], version = 1, exportSchema = false) abstract class BitsyDatabase : RoomDatabase() { abstract fun assetDao(): AssetDao abstract fun balanceDao(): BalanceDao abstract fun userAccountDao(): UserAccountDao abstract fun authorityDao(): AuthorityDao + abstract fun userAccountAuthorityDao(): UserAccountAuthorityDao companion object { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt new file mode 100644 index 0000000..d263509 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt @@ -0,0 +1,17 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.Authority + +@Dao +interface UserAccountAuthorityDao { + + @Insert + fun insert(userAccountAuthorityDao: UserAccountAuthorityDao) + + @Query("SELECT * FROM user_accounts INNER JOIN user_accounts__authorities ON user_accounts.id=user_accounts__authorities.user_account_id WHERE user_accounts__authorities.user_account_id=:userAccountId") + fun getAuthoritiesForUserAccount(userAccountId: String): LiveData> +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt index 9bb78f4..5319b6f 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt @@ -9,9 +9,9 @@ import cy.agorise.bitsybitshareswallet.models.UserAccount @Dao interface UserAccountDao { - @Query("SELECT * FROM user_accounts") - fun getAllUserAccounts(): LiveData> - @Insert fun insert(userAccount: UserAccount) + + @Query("SELECT * FROM user_accounts") + fun getAllUserAccounts(): LiveData> } \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt index 38d6c80..70ee83b 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt @@ -2,18 +2,9 @@ package cy.agorise.bitsybitshareswallet.models import androidx.room.ColumnInfo import androidx.room.Entity -import androidx.room.ForeignKey import androidx.room.PrimaryKey -@Entity(tableName = "authorities", foreignKeys = - [ForeignKey( - entity = UserAccount::class, - parentColumns = ["id"], - childColumns = ["user_id"], - onUpdate = ForeignKey.CASCADE, - onDelete = ForeignKey.CASCADE - )] -) +@Entity(tableName = "authorities") data class Authority ( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long, diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt index 8bfd802..47e2900 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt @@ -3,9 +3,10 @@ package cy.agorise.bitsybitshareswallet.models import androidx.room.ColumnInfo import androidx.room.Entity -@Entity(tableName = "balances", primaryKeys = ["user_id", "asset_id"]) +@Entity(tableName = "balances", primaryKeys = ["user_account_id", "asset_id"]) +// TODO verify if we can add user_account_id as primary key data class Balance( - @ColumnInfo(name = "user_id") val userId: String, + @ColumnInfo(name = "user_account_id") val userAccountId: String, @ColumnInfo(name = "asset_id") val assetId: String, @ColumnInfo(name = "asset_amount") val assetAmount: Long, @ColumnInfo(name = "last_update") val lastUpdate: Long diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/EquivalentValue.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/EquivalentValue.kt index 19a126d..d37cf33 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/EquivalentValue.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/EquivalentValue.kt @@ -9,15 +9,11 @@ import androidx.room.PrimaryKey [ForeignKey( entity = Transfer::class, parentColumns = ["operation_id"], - childColumns = ["transfer_id"], - onUpdate = ForeignKey.CASCADE, - onDelete = ForeignKey.CASCADE + childColumns = ["transfer_id"] ), ForeignKey( entity = Asset::class, parentColumns = ["id"], - childColumns = ["asset_id"], - onUpdate = ForeignKey.CASCADE, - onDelete = ForeignKey.CASCADE + childColumns = ["asset_id"] )] ) data class EquivalentValue ( diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Transfer.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Transfer.kt index abf1456..b582d55 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Transfer.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Transfer.kt @@ -9,20 +9,18 @@ import androidx.room.PrimaryKey [ForeignKey( entity = Operation::class, parentColumns = ["id"], - childColumns = ["operation_id"], - onUpdate = ForeignKey.CASCADE, - onDelete = ForeignKey.CASCADE + childColumns = ["operation_id"] )] ) data class Transfer ( @PrimaryKey @ColumnInfo(name = "operation_id") val operationId: String, @ColumnInfo(name = "fee_amount") val feeAmount: Long, - @ColumnInfo(name = "fee_asset_id") val feeAssetId: String, - @ColumnInfo(name = "source") val source: String, - @ColumnInfo(name = "destination") val destination: String, + @ColumnInfo(name = "fee_asset_id") val feeAssetId: String, // TODO should be foreign key to Asset + @ColumnInfo(name = "source") val source: String, // TODO should be foreign key to UserAccount + @ColumnInfo(name = "destination") val destination: String, // TODO should be foreign key to UserAccount @ColumnInfo(name = "transfer_amount") val transferAmount: Long, - @ColumnInfo(name = "transfer_asset_id") val transferAssetId: String, + @ColumnInfo(name = "transfer_asset_id") val transferAssetId: String, // TODO should be foreign key to Asset @ColumnInfo(name = "memo") val memo: String, @ColumnInfo(name = "memo_from_key") val memoFromKey: String, @ColumnInfo(name = "memo_to_key") val memoToKey: String diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt index 7ed6aa9..ad6a3b5 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt @@ -9,5 +9,6 @@ data class UserAccount ( @PrimaryKey @ColumnInfo(name = "id") val id: String, @ColumnInfo(name = "name") val name: String, - @ColumnInfo(name = "is_ltm") val isLtm: Boolean // Todo verify data type + @ColumnInfo(name = "is_ltm") val isLtm: Boolean, // Todo verify data type + @ColumnInfo(name = "weight_threshold") val weightThreshold: Int // TODO verify data type ) \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccountAuthority.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccountAuthority.kt new file mode 100644 index 0000000..6eb09ef --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccountAuthority.kt @@ -0,0 +1,25 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey + +/** + * Table to create a N:N relationship between [UserAccount] and [Authority] + */ +@Entity(tableName = "user_accounts__authorities", + primaryKeys = ["user_account_id", "authority_id"], + foreignKeys = [ForeignKey( + entity = UserAccount::class, + parentColumns = ["id"], + childColumns = ["user_account_id"] + ), ForeignKey( + entity = Authority::class, + parentColumns = ["id"], + childColumns = ["authority_id"] + )]) +data class UserAccountAuthority ( + @ColumnInfo(name = "user_account_id") val userAccountId: String, + @ColumnInfo(name = "authority_id") val authorityId: Long, + @ColumnInfo(name = "weight") val weight: Int // TODO verify data type +) \ No newline at end of file From 1932b27f7e97c7865aa5e238d7484f477de26332 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 1 Nov 2018 12:52:20 -0600 Subject: [PATCH 007/129] Fix Authority db table schema --- .../cy/agorise/bitsybitshareswallet/models/Authority.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt index 70ee83b..3f018d5 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Authority.kt @@ -8,9 +8,6 @@ import androidx.room.PrimaryKey data class Authority ( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long, - @ColumnInfo(name = "encrypted_brainkey") val encryptedBrainkey: String, - @ColumnInfo(name = "encrypted_sequence_number") val encryptedSequenceNumber: String, // TODO verify data type - @ColumnInfo(name = "encrypted_wif") val encryptedWif: String, - @ColumnInfo(name = "user_id") val userId: String, - @ColumnInfo(name = "authority_type") val authorityType: Int + @ColumnInfo(name = "encrypted_private_key") val encryptedBrainkey: String, + @ColumnInfo(name = "user_id") val userId: String ) \ No newline at end of file From ff43dcc4f489fb193b6490819c1551a787aa3e71 Mon Sep 17 00:00:00 2001 From: "Nelson R. Perez" Date: Thu, 1 Nov 2018 14:50:18 -0500 Subject: [PATCH 008/129] Included a brain key model and simple DAO stub --- .../bitsybitshareswallet/daos/BitsyDatabase.kt | 7 ++++++- .../bitsybitshareswallet/daos/BrainKeyDao.kt | 16 ++++++++++++++++ .../bitsybitshareswallet/models/BrainKey.kt | 13 +++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/models/BrainKey.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt index b428930..d5f0613 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt @@ -11,7 +11,11 @@ import cy.agorise.bitsybitshareswallet.models.* Balance::class, UserAccount::class, Authority::class, - UserAccountAuthority::class + UserAccountAuthority::class, + BrainKey::class, + EquivalentValue::class, + Operation::class, + Transfer::class ], version = 1, exportSchema = false) abstract class BitsyDatabase : RoomDatabase() { @@ -20,6 +24,7 @@ abstract class BitsyDatabase : RoomDatabase() { abstract fun userAccountDao(): UserAccountDao abstract fun authorityDao(): AuthorityDao abstract fun userAccountAuthorityDao(): UserAccountAuthorityDao + abstract fun brainKeyDao(): BrainKeyDao companion object { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt new file mode 100644 index 0000000..2432b68 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt @@ -0,0 +1,16 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.BrainKey + +@Dao +interface BrainKeyDao { + @Insert + fun insert(asset: BrainKeyDao) + + @Query("SELECT * FROM brain_keys") + fun getAllBrainKeys(): LiveData> +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/BrainKey.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/BrainKey.kt new file mode 100644 index 0000000..3d77398 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/BrainKey.kt @@ -0,0 +1,13 @@ +package cy.agorise.bitsybitshareswallet.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName="brain_keys") +data class BrainKey( + @PrimaryKey + @ColumnInfo(name = "public_key") val publicKey: String, + @ColumnInfo(name = "encrypted_brain_key") val encryptedBrainKey: String, + @ColumnInfo(name = "sequence_number") val sequenceNumber: Long +) \ No newline at end of file From eed3407b7d01b18f310d9f27278997932cf682d8 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 1 Nov 2018 14:41:10 -0600 Subject: [PATCH 009/129] Simplify Assets and UserAccounts database tables. --- .../cy/agorise/bitsybitshareswallet/models/Asset.kt | 10 +--------- .../agorise/bitsybitshareswallet/models/UserAccount.kt | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Asset.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Asset.kt index e0c03b9..fb679ff 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Asset.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Asset.kt @@ -10,14 +10,6 @@ data class Asset( @ColumnInfo(name = "id") val id: String, @ColumnInfo(name = "symbol") val symbol: String, @ColumnInfo(name = "precision") val precision: Int, - @ColumnInfo(name = "issuer") val issuer: String, @ColumnInfo(name = "description") val description: String, - @ColumnInfo(name = "max_supply") val maxSupply: Long, // TODO verify type - @ColumnInfo(name = "market_fee_percent") val marketFeePercent: Float, // TODO verify type - @ColumnInfo(name = "max_market_fee") val maxMarketFee: Float, // TODO verify type - @ColumnInfo(name = "issuer_permissions") val issuerPermissions: Int, - @ColumnInfo(name = "flags") val flags: Int, - @ColumnInfo(name = "asset_type") val assetType: Int, - @ColumnInfo(name = "bit_asset_id") val bitAssetId: String, - @ColumnInfo(name = "holders_count") val holdersCount: Int + @ColumnInfo(name = "bit_asset_id") val bitAssetId: String ) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt index ad6a3b5..c895e3f 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt @@ -9,6 +9,6 @@ data class UserAccount ( @PrimaryKey @ColumnInfo(name = "id") val id: String, @ColumnInfo(name = "name") val name: String, - @ColumnInfo(name = "is_ltm") val isLtm: Boolean, // Todo verify data type + @ColumnInfo(name = "is_ltm") val isLtm: Boolean, @ColumnInfo(name = "weight_threshold") val weightThreshold: Int // TODO verify data type ) \ No newline at end of file From 73afded9bdfd59971de616ef060e74f243306d97 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 1 Nov 2018 14:57:23 -0600 Subject: [PATCH 010/129] Add missing DAOs (Data Access Object) to use with the Room database. --- .../bitsybitshareswallet/daos/AssetDao.kt | 1 - .../bitsybitshareswallet/daos/AuthorityDao.kt | 1 - .../bitsybitshareswallet/daos/BalanceDao.kt | 1 - .../bitsybitshareswallet/daos/BitsyDatabase.kt | 17 ++++++++++------- .../daos/EquivalentValueDao.kt | 16 ++++++++++++++++ .../bitsybitshareswallet/daos/OperationDao.kt | 16 ++++++++++++++++ .../bitsybitshareswallet/daos/TransferDao.kt | 16 ++++++++++++++++ .../daos/UserAccountAuthorityDao.kt | 1 - .../bitsybitshareswallet/daos/UserAccountDao.kt | 1 - .../bitsybitshareswallet/models/Balance.kt | 2 +- 10 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/EquivalentValueDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/OperationDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/daos/TransferDao.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt index aaac373..5083f19 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt @@ -8,7 +8,6 @@ import cy.agorise.bitsybitshareswallet.models.Asset @Dao interface AssetDao { - @Insert fun insert(asset: Asset) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt index 01e743c..6eaa123 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt @@ -8,7 +8,6 @@ import cy.agorise.bitsybitshareswallet.models.Authority @Dao interface AuthorityDao { - @Insert fun insert(authority: Authority) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt index c646f78..653ee8b 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt @@ -8,7 +8,6 @@ import cy.agorise.bitsybitshareswallet.models.Balance @Dao interface BalanceDao { - @Insert fun insert(balance: Balance) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt index d5f0613..055cd8f 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt @@ -8,23 +8,26 @@ import cy.agorise.bitsybitshareswallet.models.* @Database(entities = [ Asset::class, - Balance::class, - UserAccount::class, Authority::class, - UserAccountAuthority::class, + Balance::class, BrainKey::class, EquivalentValue::class, Operation::class, - Transfer::class + Transfer::class, + UserAccount::class, + UserAccountAuthority::class ], version = 1, exportSchema = false) abstract class BitsyDatabase : RoomDatabase() { abstract fun assetDao(): AssetDao - abstract fun balanceDao(): BalanceDao - abstract fun userAccountDao(): UserAccountDao abstract fun authorityDao(): AuthorityDao - abstract fun userAccountAuthorityDao(): UserAccountAuthorityDao + abstract fun balanceDao(): BalanceDao abstract fun brainKeyDao(): BrainKeyDao + abstract fun equivalentValueDao(): EquivalentValueDao + abstract fun operationDao(): OperationDao + abstract fun transferDao(): TransferDao + abstract fun userAccountDao(): UserAccountDao + abstract fun userAccountAuthorityDao(): UserAccountAuthorityDao companion object { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/EquivalentValueDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/EquivalentValueDao.kt new file mode 100644 index 0000000..3135d5f --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/EquivalentValueDao.kt @@ -0,0 +1,16 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.EquivalentValue + +@Dao +interface EquivalentValueDao { + @Insert + fun insert(equivalentValue: EquivalentValue) + + @Query("SELECT * FROM equivalent_values") + fun getAllEquivalentValues(): LiveData> +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/OperationDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/OperationDao.kt new file mode 100644 index 0000000..a4fcf2a --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/OperationDao.kt @@ -0,0 +1,16 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.Operation + +@Dao +interface OperationDao { + @Insert + fun insert(operation: Operation) + + @Query("SELECT * FROM operations") + fun getAllOperations(): LiveData> +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/TransferDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/TransferDao.kt new file mode 100644 index 0000000..0e79fd1 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/TransferDao.kt @@ -0,0 +1,16 @@ +package cy.agorise.bitsybitshareswallet.daos + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import cy.agorise.bitsybitshareswallet.models.Transfer + +@Dao +interface TransferDao { + @Insert + fun insert(transfer: Transfer) + + @Query("SELECT * FROM transfers") + fun getAllTransfers(): LiveData> +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt index d263509..42a1b79 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt @@ -8,7 +8,6 @@ import cy.agorise.bitsybitshareswallet.models.Authority @Dao interface UserAccountAuthorityDao { - @Insert fun insert(userAccountAuthorityDao: UserAccountAuthorityDao) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt index 5319b6f..d9df243 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt @@ -8,7 +8,6 @@ import cy.agorise.bitsybitshareswallet.models.UserAccount @Dao interface UserAccountDao { - @Insert fun insert(userAccount: UserAccount) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt index 47e2900..d8c12aa 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/Balance.kt @@ -4,7 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity @Entity(tableName = "balances", primaryKeys = ["user_account_id", "asset_id"]) -// TODO verify if we can add user_account_id as primary key +// TODO make userAccountId and assetId be ForeignKeys data class Balance( @ColumnInfo(name = "user_account_id") val userAccountId: String, @ColumnInfo(name = "asset_id") val assetId: String, From 253bbd0dea33f768107f75804de52af90ffb94a8 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 1 Nov 2018 15:53:43 -0600 Subject: [PATCH 011/129] We have now verified that both the weight_threshold in UserAccount and weight in UserAccountAuthority are Integers. --- .../java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt | 2 +- .../agorise/bitsybitshareswallet/models/UserAccountAuthority.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt index c895e3f..9460ea7 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccount.kt @@ -10,5 +10,5 @@ data class UserAccount ( @ColumnInfo(name = "id") val id: String, @ColumnInfo(name = "name") val name: String, @ColumnInfo(name = "is_ltm") val isLtm: Boolean, - @ColumnInfo(name = "weight_threshold") val weightThreshold: Int // TODO verify data type + @ColumnInfo(name = "weight_threshold") val weightThreshold: Int ) \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccountAuthority.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccountAuthority.kt index 6eb09ef..99db269 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccountAuthority.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/models/UserAccountAuthority.kt @@ -21,5 +21,5 @@ import androidx.room.ForeignKey data class UserAccountAuthority ( @ColumnInfo(name = "user_account_id") val userAccountId: String, @ColumnInfo(name = "authority_id") val authorityId: Long, - @ColumnInfo(name = "weight") val weight: Int // TODO verify data type + @ColumnInfo(name = "weight") val weight: Int ) \ No newline at end of file From 16a8920ce58cefab32e28dba22a9ad628a9337b9 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 1 Nov 2018 18:45:06 -0600 Subject: [PATCH 012/129] Fix compilation errors. --- .../cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt | 2 +- .../bitsybitshareswallet/daos/UserAccountAuthorityDao.kt | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt index 2432b68..f6e4326 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BrainKeyDao.kt @@ -9,7 +9,7 @@ import cy.agorise.bitsybitshareswallet.models.BrainKey @Dao interface BrainKeyDao { @Insert - fun insert(asset: BrainKeyDao) + fun insert(brainKey: BrainKey) @Query("SELECT * FROM brain_keys") fun getAllBrainKeys(): LiveData> diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt index 42a1b79..0bfd786 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountAuthorityDao.kt @@ -5,12 +5,13 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.Query import cy.agorise.bitsybitshareswallet.models.Authority +import cy.agorise.bitsybitshareswallet.models.UserAccountAuthority @Dao interface UserAccountAuthorityDao { @Insert - fun insert(userAccountAuthorityDao: UserAccountAuthorityDao) + fun insert(userAccountAuthority: UserAccountAuthority) - @Query("SELECT * FROM user_accounts INNER JOIN user_accounts__authorities ON user_accounts.id=user_accounts__authorities.user_account_id WHERE user_accounts__authorities.user_account_id=:userAccountId") - fun getAuthoritiesForUserAccount(userAccountId: String): LiveData> +// @Query("SELECT * FROM authorities INNER JOIN user_accounts__authorities ON user_accounts.id=user_accounts__authorities.user_account_id WHERE user_accounts__authorities.user_account_id=:userAccountId") +// fun getAuthoritiesForUserAccount(userAccountId: String): LiveData> } \ No newline at end of file From 196e2f21449db0f448626d16cdfb9654c03d2933 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 21 Nov 2018 12:27:08 -0600 Subject: [PATCH 013/129] Updated graphenej gitlink --- graphenejlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphenejlib b/graphenejlib index 0b1caeb..39afcd2 160000 --- a/graphenejlib +++ b/graphenejlib @@ -1 +1 @@ -Subproject commit 0b1caeb37274e0dfdd6ca2f5439fb7ff8df609b3 +Subproject commit 39afcd26c2cd11e524956417f6ea1c1f87b60af2 From fb1d6b89fa72234bb21c7c09f1a04e00ea434c86 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 21 Nov 2018 13:13:07 -0600 Subject: [PATCH 014/129] Migrate Bitsy to MaterialComponets theme. --- app/build.gradle | 8 ++++- app/src/main/AndroidManifest.xml | 14 ++------ .../activities/SettingsActivity.kt | 2 +- app/src/main/res/layout/activity_main.xml | 2 +- app/src/main/res/values/colors.xml | 33 +------------------ app/src/main/res/values/styles.xml | 16 ++++----- 6 files changed, 19 insertions(+), 56 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e7d5f79..6e4d35e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,6 +18,9 @@ android { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } + debug { + resValue("string", "PORT_NUMBER", "8082") + } } } @@ -28,7 +31,7 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(':graphenejlib:graphenej') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.0.0' + implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2' implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' @@ -41,6 +44,9 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" + // Android Debug Database + debugImplementation 'com.amitshekhar.android:debug-db:1.0.4' + // TODO enable and make proper testing // testImplementation 'junit:junit:4.12' // testImplementation "androidx.arch.core:core-testing:$lifecycle_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6fc1626..9a78e8d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,12 +9,12 @@ android:label="@string/app_name" android:roundIcon="@drawable/bts_logo" android:supportsRtl="true" - android:theme="@style/AppTheme" + android:theme="@style/Theme.Bitsy" tools:ignore="GoogleAppIndexingWarning"> + android:theme="@style/Theme.Bitsy.NoActionBar"> @@ -29,16 +29,6 @@ - - - - \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SettingsActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SettingsActivity.kt index 173bc70..0c8a014 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SettingsActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SettingsActivity.kt @@ -21,7 +21,7 @@ class SettingsActivity : AppCompatActivity() { if (PreferenceManager.getDefaultSharedPreferences(this) .getBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, false) ) { - setTheme(R.style.AppTheme_Dark) + setTheme(R.style.Theme_Bitsy_Dark) } setContentView(R.layout.activity_settings) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index efd102d..603f11e 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -14,7 +14,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/appbar_padding_top" - android:theme="@style/AppTheme.AppBarOverlay"> + android:theme="@style/Theme.Bitsy.AppBarOverlay"> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 2a7fee2..efdc9bc 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,37 +3,6 @@ #0099d6 #0099d6 #669900 - #d3d3d3 - #686767 - #ffffff - #f0006b - #147b00 - - #000000 - #BFD1FF - #f2f6ff - #70882E - #ff0000 - #FF4081 - #DD4739 - - #FFFFFF - #FFFFFF - #000000 - - #dddddd - - #000000 - #ffffff - #669900 - #c5e1a5 - #DC473A - #ef9a9a - #BFE5F5 - #CCCCCC - - #000000 - #000000 - #ff56a9c7 + #000 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index f95b2ee..4a9d6bc 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,33 +1,31 @@ - - - - - -

BiTSy Bitshares Wallet Terms and Conditions of Use

 

The following terminology applies to these Terms and Conditions of Use (our “Terms”), the Privacy and Transparency Statement, and any and all other agreements between you and us: “Client”, “Customer”, “User”, “You” and “Your” refers to you, the person accessing the BiTSy Bitshares Wallet software application (“App”) and accepting our Terms. “Agorise”, “The Company”, “Our”, “Ourselves”, “We” and “Us” collectively refers to the App and to its owners, freelancers, developers, designers, contractors, directors, officers, employees, agents, insurers, suppliers, and attorneys. “Party” refers to either You or Us. In these Terms, unless otherwise specified, words importing the singular include the plural and vice versa and words importing gender include all genders. “Digital asset”, “asset”, “coin”, “cryptocurrency”, “ledger entry”, “altcoin” and “token” refer to blockchain-based software ledger data entries.

 

By using the App, you represent and warrant that you are:

 

  • at least 18 years old and have full capacity to contract under applicable law;
  • only transacting with the App with legally-obtained funds that belong to you;
  • not furthering, performing, undertaking, engaging in, aiding, or abetting any unlawful activity through your relationship with Us or through your use of the App; and,
  • comporting with and obeying all applicable laws.

 

We reserve the right to terminate your access to the App for any reason, including but not limited to breaches of our Terms, in our sole and absolute discretion. Use of the App is void where prohibited by applicable law.

 

  1. Terms

 

By accessing the App, you agree to be bound by our Terms, all applicable laws and regulations, and you agree that you are responsible for compliance with, and that you are compliant with applicable law. If you do not agree with any of our Terms, you are prohibited from using or accessing the App; your only recourse is to stop using the App. Any use of the App is your deemed acceptance of our Terms as they may be modified and amended from time to time. The materials contained in the App are protected by applicable copyright and trademark laws and treaties. You should check back often in case our Terms undergo changes.

 

By accepting our Terms, you expressly allow Us to export data outside of the jurisdiction in which you reside or are located when you access the App.

 

  1. Limitations

 

Use of the App may carry financial risk, and is to be used as an experimental software utility only. In no event shall We be liable or responsible for any damages, claims, applications, losses, injuries, delays, accidents, costs, business interruption costs, or other expenses (including, without limitation, attorneys’ fees or the costs of any claim or suit), nor for any incidental, direct, general, indirect, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, loss of cryptocurrency or digital assets, work stoppage, data loss, computer or device failure or malfunction, or any other commercial or other losses directly or indirectly arising out of or related to: our Terms; the Privacy and Transparency Statement; any service We provide; the use of the App; any use of your digital assets or cryptocurrency with the App by any other party not authorized by you (collectively, all of the foregoing items shall be referred to herein as “Losses”). We are hereby released by you from liability for any and all Losses. We disclaim any and all warranties or guarantees, including any warranty of merchantability and warranty of fitness for any particular purpose. The foregoing limitations of liability shall apply whether the alleged liability or Losses are based on contract, negligence, tort, strict liability, or any other basis, even if We have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of other remedies. Notwithstanding anything else in our Terms, in no event shall the combined aggregate liability for any Loss hereunder exceed 50.00€.

 

  1. Prices, Surety, Exchange Rates and Confirmations

 

Cryptocurrencies and digital assets are highly experimental and risky. Our App attempts to provide accurate price and exchange rate information, but this information is highly volatile and can change quickly without users necessarily being aware of these changes.

 

The confirmation time of some cryptocurrencies can be very lengthy. For example, if a customer pays with Bitcoin but pays a minimal miner fee when sending their funds to the App, then that customer’s payment may not be processed by that network for hours, if at all. Due to this limitation, the App offers a Surety feature, allowing you to pre-fund a blockchain account (shared with Us). If enough bridge Surety has been pre-funded into that account, then the App will notify the customer immediately that their payment has been accepted. This Surety feature in the App is known as the “Morphit” bridge. The bridge instantly locks away some of your pre-funded Surety until at least one block confirmation has been received on that customer’s transaction. Once one confirmation has been received by the bridge, then the bridge will unlock those funds back into the shared blockchain account. If the customer’s payment is never confirmed in even one block, then that amount of Surety that was locked away will not be released back to you.

Bridge Surety is not needed, or used in the App for customers that choose to pay with a cryptocurrency that uses an EOS or Graphene-based blockchain such as Bitshares or Steem, since those blockchains confirm transactions in 3 seconds or less.

 

The more bridge Surety that you pre-fund in the App, the more slow (lengthy confirmation time) coins that you can accept at once. Typically though, 100€ worth of Surety should be enough since customer’s that use slow coins don’t spend more than that at once. However, if you have 2 or 3 cash registers (or Waitresses, etc), then you may want to double or triple that amount. Of course if you sell expensive items such as cars or houses for Bitcoin, then you should pre-fund much more in Surety and/or ask your customer to pay the maximum miner fee.

 

The exchange rate that the customer pays (if applicable) is calculated at the moment the App presents the amount due to the customer (via the QR Code or NFC signal). Due to individual blockchain specifications, the customer payment is typically considered “accepted” at one block confirmation. If the bridge had to be used (because your customer paid with a slow coin), the bridge will then release the Surety back to you that was locked away while the bridge was awaiting that one block confirmation. It is important to note that a payment being broadcast to a blockchain network does not constitute an acceptance by Us of that payment.

 

  1. Returns and Refund Policy

 

Cryptocurrencies, tokens, and digital assets are, by their nature, generally irreversible, and their exchange rates are highly volatile and transitory. Once the User’s asset has been transmitted to the User’s address, no refund is possible, even if the wrong address was provided to the App. All sales after transmission are final.

Surety can be 100% refunded at any time from within the App itself. With no pre-funded bridge Surety however, only EOS or Graphene based cryptocurrencies should be accepted.

 

  1. Governing Law

 

These Terms are governed by the laws of Cyprus, and any and all laws applicable therein.

 

Our Terms are to be treated in all respects as a Cypriot contract. We and you irrevocably and unconditionally attorn to the non-exclusive jurisdiction, venue and forum of the courts of Nicosia, Cyprus, and all courts competent to hear appeals therefrom.

 

  1. Prohibited Jurisdictions

 

It is prohibited to use or access cryptocurrencies and/or Digital assets from certain jurisdictions. Transactions from Users in these jurisdictions are prohibited. By accessing the App or any services therein, you represent and warrant that you are not physically located in a prohibited jurisdiction.

 

  1. Permissible Use

 

The App and all its services may be used only as a mechanism of software ledger entry translation between the User and the BitShares blockchain. You are prohibited from using the App for the purpose of translating ledger entries with other parties, with the exception of explicit payment for goods and services.

 

  1. Terms of Use Modifications

 

We may revise our Terms at any time and without notice to you or third parties. By using the App, you agree to be bound by the then-current version of our Terms. We reserve the right to make any changes retroactive.

 

  1. Costs

 

From time to time, We may need to spend time dealing with issues brought to Us by customers. Where any customer issue is not caused by our negligence or oversight, We reserve the right to recover reasonable administrative costs spent addressing the customer issue.

 

Privacy and Transparency Statement

 

We respect the privacy of Users of Our App by not requesting any information that is unnecessary for the use of the service or to comport with our obligations under applicable law.

 

We also do not in any way obscure the information that it does request or obtain. Due to the inherent transparency of blockchains, transactions to and from the App are public and easily correlated. Utilizing the App to obscure transactions or assets in any way is futile. Law enforcement has full access to blockchain information that goes in or out of the BitShares network.

 

You accept that We will comply willingly with all legal requests for information from it. We reserve the right to provide information to law enforcement personnel and other third parties to answer inquiries; to respond to legal process; to respond to the order of a court of competent jurisdiction and those exercising the court’s authority; and, to protect Ourselves and our users.

 

Copyright 2018 AGORISE, LTD.

An International Business Co.

Cyprus Reg# HE375959

 

IF YOU AGREE TO ALL OF THESE TERMS AND CONDITIONS, PLEASE TAP ON THE GREEN BUTTON BELOW



]]> + + + Agree + Disagree + MainActivity Receive diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 4a9d6bc..cb43b60 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -25,6 +25,20 @@ true + + + + + + + From dfa5df7e8396b61c4c563d824ce4338b1cb3b9d7 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 21 Nov 2018 20:53:45 -0600 Subject: [PATCH 018/129] Create ImportBrainkeyActivity lyout. --- .../res/layout/activity_import_brainkey.xml | 98 +++++++++++++++++-- app/src/main/res/values/dimens.xml | 5 + app/src/main/res/values/strings.xml | 9 +- app/src/main/res/values/styles.xml | 2 + 4 files changed, 107 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/layout/activity_import_brainkey.xml b/app/src/main/res/layout/activity_import_brainkey.xml index 183b943..439764c 100644 --- a/app/src/main/res/layout/activity_import_brainkey.xml +++ b/app/src/main/res/layout/activity_import_brainkey.xml @@ -1,13 +1,99 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_height="match_parent" + android:focusableInTouchMode="true" + android:orientation="vertical" + tools:context=".activities.ImportBrainkeyActivity"> - + android:layout_marginTop="@dimen/activity_vertical_margin" + android:layout_marginStart="@dimen/activity_horizontal_margin" + android:layout_marginEnd="@dimen/activity_horizontal_margin" + android:hint="@string/text_field__6_digit_pin" + app:passwordToggleEnabled="true"> - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 9d518a5..808684c 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -7,4 +7,9 @@ 35sp + + 16dp + 24dp + 40dp +
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ba9791d..f07a99b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,12 +1,19 @@ BiTSy -

BiTSy Bitshares Wallet Terms and Conditions of Use

 

The following terminology applies to these Terms and Conditions of Use (our “Terms”), the Privacy and Transparency Statement, and any and all other agreements between you and us: “Client”, “Customer”, “User”, “You” and “Your” refers to you, the person accessing the BiTSy Bitshares Wallet software application (“App”) and accepting our Terms. “Agorise”, “The Company”, “Our”, “Ourselves”, “We” and “Us” collectively refers to the App and to its owners, freelancers, developers, designers, contractors, directors, officers, employees, agents, insurers, suppliers, and attorneys. “Party” refers to either You or Us. In these Terms, unless otherwise specified, words importing the singular include the plural and vice versa and words importing gender include all genders. “Digital asset”, “asset”, “coin”, “cryptocurrency”, “ledger entry”, “altcoin” and “token” refer to blockchain-based software ledger data entries.

 

By using the App, you represent and warrant that you are:

 

  • at least 18 years old and have full capacity to contract under applicable law;
  • only transacting with the App with legally-obtained funds that belong to you;
  • not furthering, performing, undertaking, engaging in, aiding, or abetting any unlawful activity through your relationship with Us or through your use of the App; and,
  • comporting with and obeying all applicable laws.

 

We reserve the right to terminate your access to the App for any reason, including but not limited to breaches of our Terms, in our sole and absolute discretion. Use of the App is void where prohibited by applicable law.

 

  1. Terms

 

By accessing the App, you agree to be bound by our Terms, all applicable laws and regulations, and you agree that you are responsible for compliance with, and that you are compliant with applicable law. If you do not agree with any of our Terms, you are prohibited from using or accessing the App; your only recourse is to stop using the App. Any use of the App is your deemed acceptance of our Terms as they may be modified and amended from time to time. The materials contained in the App are protected by applicable copyright and trademark laws and treaties. You should check back often in case our Terms undergo changes.

 

By accepting our Terms, you expressly allow Us to export data outside of the jurisdiction in which you reside or are located when you access the App.

 

  1. Limitations

 

Use of the App may carry financial risk, and is to be used as an experimental software utility only. In no event shall We be liable or responsible for any damages, claims, applications, losses, injuries, delays, accidents, costs, business interruption costs, or other expenses (including, without limitation, attorneys’ fees or the costs of any claim or suit), nor for any incidental, direct, general, indirect, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, loss of cryptocurrency or digital assets, work stoppage, data loss, computer or device failure or malfunction, or any other commercial or other losses directly or indirectly arising out of or related to: our Terms; the Privacy and Transparency Statement; any service We provide; the use of the App; any use of your digital assets or cryptocurrency with the App by any other party not authorized by you (collectively, all of the foregoing items shall be referred to herein as “Losses”). We are hereby released by you from liability for any and all Losses. We disclaim any and all warranties or guarantees, including any warranty of merchantability and warranty of fitness for any particular purpose. The foregoing limitations of liability shall apply whether the alleged liability or Losses are based on contract, negligence, tort, strict liability, or any other basis, even if We have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of other remedies. Notwithstanding anything else in our Terms, in no event shall the combined aggregate liability for any Loss hereunder exceed 50.00€.

 

  1. Prices, Surety, Exchange Rates and Confirmations

 

Cryptocurrencies and digital assets are highly experimental and risky. Our App attempts to provide accurate price and exchange rate information, but this information is highly volatile and can change quickly without users necessarily being aware of these changes.

 

The confirmation time of some cryptocurrencies can be very lengthy. For example, if a customer pays with Bitcoin but pays a minimal miner fee when sending their funds to the App, then that customer’s payment may not be processed by that network for hours, if at all. Due to this limitation, the App offers a Surety feature, allowing you to pre-fund a blockchain account (shared with Us). If enough bridge Surety has been pre-funded into that account, then the App will notify the customer immediately that their payment has been accepted. This Surety feature in the App is known as the “Morphit” bridge. The bridge instantly locks away some of your pre-funded Surety until at least one block confirmation has been received on that customer’s transaction. Once one confirmation has been received by the bridge, then the bridge will unlock those funds back into the shared blockchain account. If the customer’s payment is never confirmed in even one block, then that amount of Surety that was locked away will not be released back to you.

Bridge Surety is not needed, or used in the App for customers that choose to pay with a cryptocurrency that uses an EOS or Graphene-based blockchain such as Bitshares or Steem, since those blockchains confirm transactions in 3 seconds or less.

 

The more bridge Surety that you pre-fund in the App, the more slow (lengthy confirmation time) coins that you can accept at once. Typically though, 100€ worth of Surety should be enough since customer’s that use slow coins don’t spend more than that at once. However, if you have 2 or 3 cash registers (or Waitresses, etc), then you may want to double or triple that amount. Of course if you sell expensive items such as cars or houses for Bitcoin, then you should pre-fund much more in Surety and/or ask your customer to pay the maximum miner fee.

 

The exchange rate that the customer pays (if applicable) is calculated at the moment the App presents the amount due to the customer (via the QR Code or NFC signal). Due to individual blockchain specifications, the customer payment is typically considered “accepted” at one block confirmation. If the bridge had to be used (because your customer paid with a slow coin), the bridge will then release the Surety back to you that was locked away while the bridge was awaiting that one block confirmation. It is important to note that a payment being broadcast to a blockchain network does not constitute an acceptance by Us of that payment.

 

  1. Returns and Refund Policy

 

Cryptocurrencies, tokens, and digital assets are, by their nature, generally irreversible, and their exchange rates are highly volatile and transitory. Once the User’s asset has been transmitted to the User’s address, no refund is possible, even if the wrong address was provided to the App. All sales after transmission are final.

Surety can be 100% refunded at any time from within the App itself. With no pre-funded bridge Surety however, only EOS or Graphene based cryptocurrencies should be accepted.

 

  1. Governing Law

 

These Terms are governed by the laws of Cyprus, and any and all laws applicable therein.

 

Our Terms are to be treated in all respects as a Cypriot contract. We and you irrevocably and unconditionally attorn to the non-exclusive jurisdiction, venue and forum of the courts of Nicosia, Cyprus, and all courts competent to hear appeals therefrom.

 

  1. Prohibited Jurisdictions

 

It is prohibited to use or access cryptocurrencies and/or Digital assets from certain jurisdictions. Transactions from Users in these jurisdictions are prohibited. By accessing the App or any services therein, you represent and warrant that you are not physically located in a prohibited jurisdiction.

 

  1. Permissible Use

 

The App and all its services may be used only as a mechanism of software ledger entry translation between the User and the BitShares blockchain. You are prohibited from using the App for the purpose of translating ledger entries with other parties, with the exception of explicit payment for goods and services.

 

  1. Terms of Use Modifications

 

We may revise our Terms at any time and without notice to you or third parties. By using the App, you agree to be bound by the then-current version of our Terms. We reserve the right to make any changes retroactive.

 

  1. Costs

 

From time to time, We may need to spend time dealing with issues brought to Us by customers. Where any customer issue is not caused by our negligence or oversight, We reserve the right to recover reasonable administrative costs spent addressing the customer issue.

 

Privacy and Transparency Statement

 

We respect the privacy of Users of Our App by not requesting any information that is unnecessary for the use of the service or to comport with our obligations under applicable law.

 

We also do not in any way obscure the information that it does request or obtain. Due to the inherent transparency of blockchains, transactions to and from the App are public and easily correlated. Utilizing the App to obscure transactions or assets in any way is futile. Law enforcement has full access to blockchain information that goes in or out of the BitShares network.

 

You accept that We will comply willingly with all legal requests for information from it. We reserve the right to provide information to law enforcement personnel and other third parties to answer inquiries; to respond to legal process; to respond to the order of a court of competent jurisdiction and those exercising the court’s authority; and, to protect Ourselves and our users.

 

Copyright 2018 AGORISE, LTD.

An International Business Co.

Cyprus Reg# HE375959

 

IF YOU AGREE TO ALL OF THESE TERMS AND CONDITIONS, PLEASE TAP ON THE GREEN BUTTON BELOW



]]>
+

BiTSy Bitshares Wallet Terms and Conditions of Use

 

The following terminology applies to these Terms and Conditions of Use (our “Terms”), the Privacy and Transparency Statement, and any and all other agreements between you and us: “Client”, “Customer”, “User”, “You” and “Your” refers to you, the person accessing the BiTSy Bitshares Wallet software application (“App”) and accepting our Terms. “Agorise”, “The Company”, “Our”, “Ourselves”, “We” and “Us” collectively refers to the App and to its owners, freelancers, developers, designers, contractors, directors, officers, employees, agents, insurers, suppliers, and attorneys. “Party” refers to either You or Us. In these Terms, unless otherwise specified, words importing the singular include the plural and vice versa and words importing gender include all genders. “Digital asset”, “asset”, “coin”, “cryptocurrency”, “ledger entry”, “altcoin” and “token” refer to blockchain-based software ledger data entries.

 

By using the App, you represent and warrant that you are:

 

  • at least 18 years old and have full capacity to contract under applicable law;
  • only transacting with the App with legally-obtained funds that belong to you;
  • not furthering, performing, undertaking, engaging in, aiding, or abetting any unlawful activity through your relationship with Us or through your use of the App; and,
  • comporting with and obeying all applicable laws.

 

We reserve the right to terminate your access to the App for any reason, including but not limited to breaches of our Terms, in our sole and absolute discretion. Use of the App is void where prohibited by applicable law.

 

  1. Terms

 

By accessing the App, you agree to be bound by our Terms, all applicable laws and regulations, and you agree that you are responsible for compliance with, and that you are compliant with applicable law. If you do not agree with any of our Terms, you are prohibited from using or accessing the App; your only recourse is to stop using the App. Any use of the App is your deemed acceptance of our Terms as they may be modified and amended from time to time. The materials contained in the App are protected by applicable copyright and trademark laws and treaties. You should check back often in case our Terms undergo changes.

 

By accepting our Terms, you expressly allow Us to export data outside of the jurisdiction in which you reside or are located when you access the App.

 

  1. Limitations

 

Use of the App may carry financial risk, and is to be used as an experimental software utility only. In no event shall We be liable or responsible for any damages, claims, applications, losses, injuries, delays, accidents, costs, business interruption costs, or other expenses (including, without limitation, attorneys’ fees or the costs of any claim or suit), nor for any incidental, direct, general, indirect, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, loss of cryptocurrency or digital assets, work stoppage, data loss, computer or device failure or malfunction, or any other commercial or other losses directly or indirectly arising out of or related to: our Terms; the Privacy and Transparency Statement; any service We provide; the use of the App; any use of your digital assets or cryptocurrency with the App by any other party not authorized by you (collectively, all of the foregoing items shall be referred to herein as “Losses”). We are hereby released by you from liability for any and all Losses. We disclaim any and all warranties or guarantees, including any warranty of merchantability and warranty of fitness for any particular purpose. The foregoing limitations of liability shall apply whether the alleged liability or Losses are based on contract, negligence, tort, strict liability, or any other basis, even if We have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of other remedies. Notwithstanding anything else in our Terms, in no event shall the combined aggregate liability for any Loss hereunder exceed 50.00€.

 

  1. Prices, Surety, Exchange Rates and Confirmations

 

Cryptocurrencies and digital assets are highly experimental and risky. Our App attempts to provide accurate price and exchange rate information, but this information is highly volatile and can change quickly without users necessarily being aware of these changes.

 

The confirmation time of some cryptocurrencies can be very lengthy. For example, if a customer pays with Bitcoin but pays a minimal miner fee when sending their funds to the App, then that customer’s payment may not be processed by that network for hours, if at all. Due to this limitation, the App offers a Surety feature, allowing you to pre-fund a blockchain account (shared with Us). If enough bridge Surety has been pre-funded into that account, then the App will notify the customer immediately that their payment has been accepted. This Surety feature in the App is known as the “Morphit” bridge. The bridge instantly locks away some of your pre-funded Surety until at least one block confirmation has been received on that customer’s transaction. Once one confirmation has been received by the bridge, then the bridge will unlock those funds back into the shared blockchain account. If the customer’s payment is never confirmed in even one block, then that amount of Surety that was locked away will not be released back to you.

Bridge Surety is not needed, or used in the App for customers that choose to pay with a cryptocurrency that uses an EOS or Graphene-based blockchain such as Bitshares or Steem, since those blockchains confirm transactions in 3 seconds or less.

 

The more bridge Surety that you pre-fund in the App, the more slow (lengthy confirmation time) coins that you can accept at once. Typically though, 100€ worth of Surety should be enough since customer’s that use slow coins don’t spend more than that at once. However, if you have 2 or 3 cash registers (or Waitresses, etc), then you may want to double or triple that amount. Of course if you sell expensive items such as cars or houses for Bitcoin, then you should pre-fund much more in Surety and/or ask your customer to pay the maximum miner fee.

 

The exchange rate that the customer pays (if applicable) is calculated at the moment the App presents the amount due to the customer (via the QR Code or NFC signal). Due to individual blockchain specifications, the customer payment is typically considered “accepted” at one block confirmation. If the bridge had to be used (because your customer paid with a slow coin), the bridge will then release the Surety back to you that was locked away while the bridge was awaiting that one block confirmation. It is important to note that a payment being broadcast to a blockchain network does not constitute an acceptance by Us of that payment.

 

  1. Returns and Refund Policy

 

Cryptocurrencies, tokens, and digital assets are, by their nature, generally irreversible, and their exchange rates are highly volatile and transitory. Once the User’s asset has been transmitted to the User’s address, no refund is possible, even if the wrong address was provided to the App. All sales after transmission are final.

Surety can be 100% refunded at any time from within the App itself. With no pre-funded bridge Surety however, only EOS or Graphene based cryptocurrencies should be accepted.

 

  1. Governing Law

 

These Terms are governed by the laws of Cyprus, and any and all laws applicable therein.

 

Our Terms are to be treated in all respects as a Cypriot contract. We and you irrevocably and unconditionally attorn to the non-exclusive jurisdiction, venue and forum of the courts of Nicosia, Cyprus, and all courts competent to hear appeals therefrom.

 

  1. Prohibited Jurisdictions

 

It is prohibited to use or access cryptocurrencies and/or Digital assets from certain jurisdictions. Transactions from Users in these jurisdictions are prohibited. By accessing the App or any services therein, you represent and warrant that you are not physically located in a prohibited jurisdiction.

 

  1. Permissible Use

 

The App and all its services may be used only as a mechanism of software ledger entry translation between the User and the BitShares blockchain. You are prohibited from using the App for the purpose of translating ledger entries with other parties, with the exception of explicit payment for goods and services.

 

  1. Terms of Use Modifications

 

We may revise our Terms at any time and without notice to you or third parties. By using the App, you agree to be bound by the then-current version of our Terms. We reserve the right to make any changes retroactive.

 

  1. Costs

 

From time to time, We may need to spend time dealing with issues brought to Us by customers. Where any customer issue is not caused by our negligence or oversight, We reserve the right to recover reasonable administrative costs spent addressing the customer issue.

 

Privacy and Transparency Statement

 

We respect the privacy of Users of Our App by not requesting any information that is unnecessary for the use of the service or to comport with our obligations under applicable law.

 

We also do not in any way obscure the information that it does request or obtain. Due to the inherent transparency of blockchains, transactions to and from the App are public and easily correlated. Utilizing the App to obscure transactions or assets in any way is futile. Law enforcement has full access to blockchain information that goes in or out of the BitShares network.

 

You accept that We will comply willingly with all legal requests for information from it. We reserve the right to provide information to law enforcement personnel and other third parties to answer inquiries; to respond to legal process; to respond to the order of a court of competent jurisdiction and those exercising the court’s authority; and, to protect Ourselves and our users.

 

Copyright 2018 AGORISE, LTD.

An International Business Co.

Cyprus Reg# HE375959

 

IF YOU AGREE TO ALL OF THESE TERMS AND CONDITIONS, PLEASE TAP ON THE GREEN BUTTON BELOW



]]>
Agree Disagree + + 6+ digits PIN + Confirm PIN + BrainKey + Import + Create + MainActivity Receive diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 298bc0a..ff02646 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -30,6 +30,8 @@ @drawable/splash_screen + - +

BiTSy Bitshares Wallet Terms and Conditions of Use

 

The following terminology applies to these Terms and Conditions of Use (our “Terms”), the Privacy and Transparency Statement, and any and all other agreements between you and us: “Client”, “Customer”, “User”, “You” and “Your” refers to you, the person accessing the BiTSy Bitshares Wallet software application (“App”) and accepting our Terms. “Agorise”, “The Company”, “Our”, “Ourselves”, “We” and “Us” collectively refers to the App and to its owners, freelancers, developers, designers, contractors, directors, officers, employees, agents, insurers, suppliers, and attorneys. “Party” refers to either You or Us. In these Terms, unless otherwise specified, words importing the singular include the plural and vice versa and words importing gender include all genders. “Digital asset”, “asset”, “coin”, “cryptocurrency”, “ledger entry”, “altcoin” and “token” refer to blockchain-based software ledger data entries.

 

By using the App, you represent and warrant that you are:

 

  • at least 18 years old and have full capacity to contract under applicable law;
  • only transacting with the App with legally-obtained funds that belong to you;
  • not furthering, performing, undertaking, engaging in, aiding, or abetting any unlawful activity through your relationship with Us or through your use of the App; and,
  • comporting with and obeying all applicable laws.

 

We reserve the right to terminate your access to the App for any reason, including but not limited to breaches of our Terms, in our sole and absolute discretion. Use of the App is void where prohibited by applicable law.

 

  1. Terms

 

By accessing the App, you agree to be bound by our Terms, all applicable laws and regulations, and you agree that you are responsible for compliance with, and that you are compliant with applicable law. If you do not agree with any of our Terms, you are prohibited from using or accessing the App; your only recourse is to stop using the App. Any use of the App is your deemed acceptance of our Terms as they may be modified and amended from time to time. The materials contained in the App are protected by applicable copyright and trademark laws and treaties. You should check back often in case our Terms undergo changes.

 

By accepting our Terms, you expressly allow Us to export data outside of the jurisdiction in which you reside or are located when you access the App.

 

  1. Limitations

 

Use of the App may carry financial risk, and is to be used as an experimental software utility only. In no event shall We be liable or responsible for any damages, claims, applications, losses, injuries, delays, accidents, costs, business interruption costs, or other expenses (including, without limitation, attorneys’ fees or the costs of any claim or suit), nor for any incidental, direct, general, indirect, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, loss of cryptocurrency or digital assets, work stoppage, data loss, computer or device failure or malfunction, or any other commercial or other losses directly or indirectly arising out of or related to: our Terms; the Privacy and Transparency Statement; any service We provide; the use of the App; any use of your digital assets or cryptocurrency with the App by any other party not authorized by you (collectively, all of the foregoing items shall be referred to herein as “Losses”). We are hereby released by you from liability for any and all Losses. We disclaim any and all warranties or guarantees, including any warranty of merchantability and warranty of fitness for any particular purpose. The foregoing limitations of liability shall apply whether the alleged liability or Losses are based on contract, negligence, tort, strict liability, or any other basis, even if We have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of other remedies. Notwithstanding anything else in our Terms, in no event shall the combined aggregate liability for any Loss hereunder exceed 50.00€.

 

  1. Prices, Surety, Exchange Rates and Confirmations

 

Cryptocurrencies and digital assets are highly experimental and risky. Our App attempts to provide accurate price and exchange rate information, but this information is highly volatile and can change quickly without users necessarily being aware of these changes.

 

The confirmation time of some cryptocurrencies can be very lengthy. For example, if a customer pays with Bitcoin but pays a minimal miner fee when sending their funds to the App, then that customer’s payment may not be processed by that network for hours, if at all. Due to this limitation, the App offers a Surety feature, allowing you to pre-fund a blockchain account (shared with Us). If enough bridge Surety has been pre-funded into that account, then the App will notify the customer immediately that their payment has been accepted. This Surety feature in the App is known as the “Morphit” bridge. The bridge instantly locks away some of your pre-funded Surety until at least one block confirmation has been received on that customer’s transaction. Once one confirmation has been received by the bridge, then the bridge will unlock those funds back into the shared blockchain account. If the customer’s payment is never confirmed in even one block, then that amount of Surety that was locked away will not be released back to you.

Bridge Surety is not needed, or used in the App for customers that choose to pay with a cryptocurrency that uses an EOS or Graphene-based blockchain such as Bitshares or Steem, since those blockchains confirm transactions in 3 seconds or less.

 

The more bridge Surety that you pre-fund in the App, the more slow (lengthy confirmation time) coins that you can accept at once. Typically though, 100€ worth of Surety should be enough since customer’s that use slow coins don’t spend more than that at once. However, if you have 2 or 3 cash registers (or Waitresses, etc), then you may want to double or triple that amount. Of course if you sell expensive items such as cars or houses for Bitcoin, then you should pre-fund much more in Surety and/or ask your customer to pay the maximum miner fee.

 

The exchange rate that the customer pays (if applicable) is calculated at the moment the App presents the amount due to the customer (via the QR Code or NFC signal). Due to individual blockchain specifications, the customer payment is typically considered “accepted” at one block confirmation. If the bridge had to be used (because your customer paid with a slow coin), the bridge will then release the Surety back to you that was locked away while the bridge was awaiting that one block confirmation. It is important to note that a payment being broadcast to a blockchain network does not constitute an acceptance by Us of that payment.

 

  1. Returns and Refund Policy

 

Cryptocurrencies, tokens, and digital assets are, by their nature, generally irreversible, and their exchange rates are highly volatile and transitory. Once the User’s asset has been transmitted to the User’s address, no refund is possible, even if the wrong address was provided to the App. All sales after transmission are final.

Surety can be 100% refunded at any time from within the App itself. With no pre-funded bridge Surety however, only EOS or Graphene based cryptocurrencies should be accepted.

 

  1. Governing Law

 

These Terms are governed by the laws of Cyprus, and any and all laws applicable therein.

 

Our Terms are to be treated in all respects as a Cypriot contract. We and you irrevocably and unconditionally attorn to the non-exclusive jurisdiction, venue and forum of the courts of Nicosia, Cyprus, and all courts competent to hear appeals therefrom.

 

  1. Prohibited Jurisdictions

 

It is prohibited to use or access cryptocurrencies and/or Digital assets from certain jurisdictions. Transactions from Users in these jurisdictions are prohibited. By accessing the App or any services therein, you represent and warrant that you are not physically located in a prohibited jurisdiction.

 

  1. Permissible Use

 

The App and all its services may be used only as a mechanism of software ledger entry translation between the User and the BitShares blockchain. You are prohibited from using the App for the purpose of translating ledger entries with other parties, with the exception of explicit payment for goods and services.

 

  1. Terms of Use Modifications

 

We may revise our Terms at any time and without notice to you or third parties. By using the App, you agree to be bound by the then-current version of our Terms. We reserve the right to make any changes retroactive.

 

  1. Costs

 

From time to time, We may need to spend time dealing with issues brought to Us by customers. Where any customer issue is not caused by our negligence or oversight, We reserve the right to recover reasonable administrative costs spent addressing the customer issue.

 

Privacy and Transparency Statement

 

We respect the privacy of Users of Our App by not requesting any information that is unnecessary for the use of the service or to comport with our obligations under applicable law.

 

We also do not in any way obscure the information that it does request or obtain. Due to the inherent transparency of blockchains, transactions to and from the App are public and easily correlated. Utilizing the App to obscure transactions or assets in any way is futile. Law enforcement has full access to blockchain information that goes in or out of the BitShares network.

 

You accept that We will comply willingly with all legal requests for information from it. We reserve the right to provide information to law enforcement personnel and other third parties to answer inquiries; to respond to legal process; to respond to the order of a court of competent jurisdiction and those exercising the court’s authority; and, to protect Ourselves and our users.

 

Copyright 2018 AGORISE, LTD.

An International Business Co.

Cyprus Reg# HE375959

 

IF YOU AGREE TO ALL OF THESE TERMS AND CONDITIONS, PLEASE TAP ON THE GREEN BUTTON BELOW



]]> +

                  

BiTSy Terms and Conditions of Use

 

BiTSy is a software Application (also known as an “App”) developed by the International Business Company “AGORISE, LTD.”, which has been established under Cypriot law. Any person wishing to use this App is obliged to accept the following Terms and Conditions of Use, before any such use:

 

Part I - Terminology

 

The following Terminology applies to these Terms and Conditions of Use (hereinafter referred to as “Terms”), the Privacy and Transparency Statement, and all other agreements between You and Us:

  • The terms “Client”, “Customer”, “Merchant”, “User”, “You” and “Your” refer to you, the person accessing the BiTSy software Application (hereinafter referred to as “App”) and hereby accepting our Terms.
  • The terms “Agorise”, “The Company”, “Our”, “Ourselves”, “We” and “Us” collectively refer to the App and to its owners, freelancers, developers, designers, contractors, directors, officers, employees, agents, insurers, suppliers, and attorneys.
  • The term “Party” refers to either You or Us.
  • In all the above-mentioned Terms, unless otherwise specified, words using the singular include the plural and vice versa and words using gender include all genders.
  • The terms “digital asset”, “asset”, “coin”, “cryptocurrency”, “ledger entry”, “altcoin” and “token” refer to blockchain-based software ledger data entries.
  • The term “Blockchain” refers to a chain of blocks, processed by hundreds of computers around the world. A blockchain (like “Bitshares”) is a decentralized network of computers, an immutable distributed ledger. As each block of transactions is confirmed every 3 (three) seconds, it is hashed together with the latest block in the chain, forming the next block in the chain. Hence the term blockchain.
  • The term “Ledger” refers to a digital version of the “big book” of blocks of transactions taking place on a blockchain. The Distributed ledger keeps track of all transactions on a blockchain network.
  • The name “Morphit” refers to the name chosen by our Company for the Bridge.
  • The term “Bridge” refers to a company or autonomous software (like the “Morphit” feature of our App) which converts/morphs one cryptocurrency into another by way of seeking the best possible price for the Customer by using various third-party exchanges.
  • The terms “Teller” or “Gateway” refers to a person or company (or autonomous software) that converts “fiat” (USD, EUR, CNY, etc) into cryptocurrencies, and vice-versa, whether by cash, card, Swift or SEPA, etc.
  • The term “Multisig” refers to Multiple Signatories. Multiple people or accounts that are assigned to validate a transaction before it can be allowed to be processed, and entered into a block on the chain. Typically, two or more people sign the transaction with their private key (Public Key Infrastructure (PKI)) which will approve the transaction to be sent.
  • For the term “Bitshares” more information can usually be found at the website: http://www.bitshares.org
  • The term “Coin” refers to a digital token. It is underlined that this term is still loosely defined in legislation. It’s a unit of value (if it has any value at all, as determined by the free market) which is running on a blockchain.
  • The term “BTS” refers to the core token that the Bitshares platform uses to determine fair-market values for tokens.

 

Part II - Terms and Conditions of Use

 

By using the App, you represent and warrant that you are:

  1. at least 18 (eighteen) years old and have full capacity to contract under the applicable law;
  2. only transacting with the App with legally-obtained funds that belong to you;
  3. not furthering, performing, undertaking, engaging in, aiding, or abetting any unlawful activity through your relationship with Us or through your use of the App (for example: money laundering, etc); and,
  4. comporting with and obeying all applicable laws.

 

We reserve the right to terminate your access to the App for any breach or our Terms, in our sole and absolute discretion, if the App ceases to exist and/or following a decision of the Company. Use of the App is void where prohibited by applicable law.

 

1. Terms

 

1.1 By accessing the App, you agree to be bound by our Terms, all applicable laws and regulations in Cyprus, and you agree that you are responsible for compliance with, and that you are compliant with applicable law.

 

1.2 If you do not agree with any of our Terms, you are prohibited from using or accessing the App. Your only recourse is to stop using the App. Any use of the App after accepting these Terms is considered to be a deemed acceptance of our Terms, as they may be modified and amended from time to time.

 

1.3 The materials contained in the App are protected by applicable copyright and trademark laws in Cyprus and EU and international treaties. The updates of our Terms, as they appear on our website, take into account the legislative modifications.

 

1.4 By accepting our Terms, you expressly accept that data of transactions made when accessing the App might be exported outside the jurisdiction in which you reside or are located when you access the App. This export is an inherent part of our App and is necessary for its functioning and does not include personal data of Users in any way.

 

1.5 By using any of the third-parties linked to within the App (such as Tellers or Gateways), it is not an endorsement of those third-parties, nor is it a guarantee of any kind that using those third-parties will not result in loss of funds or other damages. Use those third-parties at your own risk.

 

2. Limitations

 

The use of this App may carry financial risk for any User, and is to be used as an experimental software utility only. In no event shall We be liable or responsible for any damages, claims, applications, losses, injuries, delays, accidents, costs, business interruption costs, or other expenses (including, without limitation, attorneys’ fees or the costs of any claim or suit), nor for any incidental, direct, general, indirect, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, loss of cryptocurrency or digital assets, work stoppage, computer or device failure or malfunction, or any other commercial or other losses directly or indirectly arising out of or related to:

  1. our Terms;
  2. the Privacy and Transparency Statement;
  3. any service We provide;
  4. the use of the App;
  5. any use of your digital assets or cryptocurrency with the App by any other party not authorized by you (collectively, all of the foregoing items shall be referred to herein as “Losses”).

 

We are hereby released by You from liability for any kind of the above-mentioned Losses. We disclaim any and all warranties or guarantees, including any warranty of merchantability and warranty of fitness for any particular purpose.

 

The foregoing limitations of liability shall apply whether the alleged liability or Losses are based on contract, negligence, tort, strict liability, or any other basis, even if We have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of other remedies. Notwithstanding anything else in our Terms, in no event shall the combined aggregate liability for any Loss hereunder exceed € 50.00 (fifty euros).

 

3. Prices, Exchange Rates, Surety and Confirmations

 

3.1 Users are hereby informed that Cryptocurrencies and digital assets in general are highly experimental and risky. Our App attempts to provide accurate price and exchange rate information, but this information is as well highly volatile and can change quickly without Users or Us necessarily being aware of these changes.

 

3.2 The exchange rate that the Customer pays (if applicable) is calculated at the moment the App presents the amount due to the customer (via the QR Code or NFC signal). Our App will always seek out the best price for the Customer.

3.3 The confirmation time of some cryptocurrencies can be very lengthy. For example, if a customer pays with a slow coin such as the Petro (Venezuela) but pays a minimal miner fee when sending their funds to the App, then that customer’s payment may not be processed by that network for many hours, if at all.

 

Due to this risk, the App offers a Surety feature, allowing You to voluntarily pre-fund a Multisig blockchain account (for example: joes-grocery-morphit) with some Bitshares (BTS) tokens, and then voluntarily share that account with the Morphit bridge algorithm in the App temporarily.

 

This way, the bridge can send the necessary BTS or smartcoins to the Merchant instantly, be protected from customer minimal miner fee or double-spend scams, and confirm the customers "completed" payment so that the customer doesn't have to stand there waiting for their (slow coin) payment to confirm. The customer can then theoretically pay with any supported coin and leave in as little as 3 seconds. Payments in a Bitshares token do not require use of a bridge or surety at all since that chain is so fast. Steem payments don't need surety either, but the bridge is used real quick to convert it to the merchants desired BTS or smartcoin. The merchant can empty their surety account any time they like, or add more funds to it for high volume (such as grocery chains) or larger transactions (such as homes or cars).

 

If however, the customer’s payment is never confirmed by their network, then that amount of Surety that was shared with the bridge will not be released back to You. The bridge will not assume any risk of Your customers payments not clearing.

 

Due to individual blockchain specifications, the Customer payment is typically considered “accepted” by the bridge at two block confirmations. If a bridge had to be used, the bridge will then automatically release the Surety back to you that was shared while the bridge was awaiting those two block confirmations. It is important to note that a payment being broadcast to a blockchain network does not constitute an acceptance by the App of that payment.

 

4. Returns and Refund Policy

 

4.1 Cryptocurrencies, tokens, and digital assets are, by their nature, generally irreversible, and their exchange rates are highly volatile and transitory. Once the User’s asset has been transmitted to the User’s address, no refund is possible, even if the wrong address was provided to the App. All sales after transmission are final and the Company is not in position to reverse or correct the process already undertaken by the App.

 

4.2 Surety can be 100% refunded at any time from within the App itself. With no pre-funded bridge Surety however, only EOS or Graphene-based cryptocurrencies should be accepted (such as Steem and/or Bitshares tokens).

 

5. Governing Law

 

5.1 These Terms are governed by the laws of Cyprus, and any and all laws applicable therein.

 

5.2 Our Terms are to be treated in all respects as a Cypriot contract. We and You irrevocably and unconditionally attorn to the non-exclusive jurisdiction, venue and forum of the courts of Nicosia, Cyprus, and all courts competent to hear appeals therefrom.

 

6. Permissible Use 

 

The App and all its services may be used only as a mechanism of software ledger entry translation between the User and the Bitshares blockchain. You are prohibited from using the App for the purpose of translating ledger entries with other parties, with the exception of explicit payment for goods and services.

 

7. Terms of Use Modifications 

 

7.1 We may revise our Terms at any time and without notice to you or third parties. By using the App, you agree to be bound by the then-current version of our Terms. All modifications generally apply ex nunc, unless otherwise specified in special cases, if this is justified by the circumstances.

 

7.2 The Terms as they appear on the website of our App are always up-to-date. Therefore, Users are advised to visit the relevant part of the website regularly in order to be informed of the latest changes.

 

8. Costs 

 

8.1 From time to time, We may need to spend time dealing with issues brought to Us by customers, for example requests of information.

 

8.2 Where any customer issue is not caused by our negligence or oversight, We reserve the right to recover reasonable administrative costs spent addressing the customer issue. These costs will be calculated by the Company taking into account the relevant administrative burden caused to it and will be communicated to the Customer.

 

8.3 No response will be sent to the Customer if this entails a payment from his side, before the cost is communicated to him by the email provided by him for this specific purpose.

 

9. Transparency Statement 

 

9.1 No personal data whatsoever of Users is registered, stored or processed in any way; Users are solely liable for keeping the “key” which is necessary to access the interface and in case of loss renders this access impossible. Therefore, the Regulation (EU) No 2016/679 (GDPR) is not applicable within the framework of this App.

 

9.2 We also do not in any way obscure the information that it does request or obtain. Due to the inherent transparency of blockchains, transactions to and from the App are public and easily correlated. Utilizing the App to obscure transactions or assets in any way is futile. Law enforcement has full access to blockchain information that goes in or out of the Bitshares network.

 

9.3 You accept that We will comply willingly with all legal requests for information from it. We reserve the right to provide information to law enforcement personnel and other third parties to answer inquiries; to respond to legal process; to respond to the order of a court of competent jurisdiction and those exercising the court’s authority; and, to protect Ourselves and our users.

 

Copyright 2018 AGORISE, LTD.

An International Business Co.

Cyprus Reg# HE375959

 

IF YOU AGREE TO ALL OF THESE TERMS AND CONDITIONS, PLEASE TAP ON THE GREEN BUTTON BELOW

]]>
Agree From 3cbe738fd79ec136d9e01e0614f515ed516a0577 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 28 Nov 2018 14:28:18 -0600 Subject: [PATCH 031/129] Move deleteAll method from TransferRepository to an async thread, to avoid app crashes for doing db operations in the main thread. --- .../processors/TransfersLoader.kt | 2 +- .../repositories/TransferRepository.kt | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt index 62f8d49..06deb79 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt @@ -53,7 +53,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li private val TAG = this.javaClass.name /** Constant that specifies if we are on debug mode */ - private val DEBUG = false + private val DEBUG = true /* Constant used to fix the number of historical transfers to fetch from the network in one batch */ private val HISTORICAL_TRANSFER_BATCH_SIZE = 100 diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt index 7f7f2f1..821d754 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt @@ -25,7 +25,7 @@ class TransferRepository internal constructor(context: Context) { } fun deleteAll() { - mTransferDao.deleteAll() + deleteAllAsyncTask(mTransferDao).execute() } private class insertAllAsyncTask internal constructor(private val mAsyncTaskDao: TransferDao) : @@ -36,4 +36,13 @@ class TransferRepository internal constructor(context: Context) { return null } } + + private class deleteAllAsyncTask internal constructor(private val mAsyncTaskDao: TransferDao) : + AsyncTask() { + + override fun doInBackground(vararg params: Void?): Void? { + mAsyncTaskDao.deleteAll() + return null + } + } } \ No newline at end of file From bebffa14eddf3cae7865c658eff7e25cea1b228d Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 28 Nov 2018 18:55:53 -0600 Subject: [PATCH 032/129] - Remove no needed code and simplifyy TransfersLoader, also add a CompositeDisposable to keep track of all RxJava subscriptions and be able to dispose them when the class is finished. - Call the TransfersLoader in MainActivity from a better place. --- .../activities/MainActivity.kt | 18 +- .../processors/TransfersLoader.kt | 381 ++---------------- 2 files changed, 38 insertions(+), 361 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 51e9424..6ba72d6 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -2,6 +2,7 @@ package cy.agorise.bitsybitshareswallet.activities import android.content.Intent import android.os.Bundle +import android.util.Log import android.view.Menu import android.view.MenuItem import android.widget.Toast @@ -16,6 +17,7 @@ import cy.agorise.graphenej.models.JsonRpcResponse import kotlinx.android.synthetic.main.activity_main.* class MainActivity : ConnectedActivity() { + private val TAG = this.javaClass.name private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> when (item.itemId) { @@ -86,22 +88,18 @@ class MainActivity : ConnectedActivity() { */ override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) { when (connectionStatusUpdate.updateCode) { - ConnectionStatusUpdate.CONNECTED -> { - // Instantiating this loader is enough to kick-start the transfers loading procedure - TransfersLoader(this, lifecycle) - } - ConnectionStatusUpdate.DISCONNECTED -> { - // Do nothing for now - } + ConnectionStatusUpdate.CONNECTED -> { /* Do nothing for now */ } + ConnectionStatusUpdate.DISCONNECTED -> { /* Do nothing for now */ } ConnectionStatusUpdate.AUTHENTICATED -> {}//updateBalances() } ConnectionStatusUpdate.API_UPDATE -> { // In certain cases the information about the accounts is not complete, this may not be the best // solution but at least it works. Feel free to improve it or move it to a better place //MissingAccountsLoader(this, lifecycle) - if (connectionStatusUpdate.api == ApiAccess.API_DATABASE) { - // Updating transfer and exchange costs in all possible input assets - //updateCosts() + if (connectionStatusUpdate.api == ApiAccess.API_NETWORK_BROADCAST) { + Log.d(TAG, "ConnectionStatusUpdate: API_NETWORK_BROADCAST") + // Instantiating this loader is enough to kick-start the transfers loading procedure + TransfersLoader(this, lifecycle) } } } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt index 06deb79..df93fad 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt @@ -22,12 +22,11 @@ import cy.agorise.graphenej.api.android.NetworkService import cy.agorise.graphenej.api.android.RxBus import cy.agorise.graphenej.api.calls.GetRelativeAccountHistory import cy.agorise.graphenej.errors.ChecksumException -import cy.agorise.graphenej.models.BlockHeader import cy.agorise.graphenej.models.JsonRpcResponse import cy.agorise.graphenej.models.OperationHistory import cy.agorise.graphenej.operations.TransferOperation import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.Disposable +import io.reactivex.disposables.CompositeDisposable import io.reactivex.functions.Consumer import io.reactivex.schedulers.Schedulers import org.bitcoinj.core.DumpedPrivateKey @@ -49,36 +48,20 @@ import javax.crypto.AEADBadTagException * for every transfer, we must first load all historical transfer operations, and then proceed to * handle those missing columns. */ -class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Lifecycle) : LifecycleObserver { +class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Lifecycle) : LifecycleObserver, + ServiceConnection { + private val TAG = this.javaClass.name /** Constant that specifies if we are on debug mode */ - private val DEBUG = true + private val DEBUG = false /* Constant used to fix the number of historical transfers to fetch from the network in one batch */ private val HISTORICAL_TRANSFER_BATCH_SIZE = 100 - /* Constant used to split the missing times and equivalent values in batches of constant time */ - private val MISSING_TIMES_BATCH_SIZE = 100 - - /* Constants used to specify which type of conversion will be used. A direct conversion is performed - * only between BTS -> bitUSD. For all other assets, we'll need to perform a two step conversion - * in the form XXX -> BTS -> bitUSD. That is the basic difference between direct and indirect conversions. - */ - private val DIRECT_CONVERSION: Short = 0 - private val INDIRECT_CONVERSION: Short = 1 - private val RESPONSE_GET_RELATIVE_ACCOUNT_HISTORY = 0 - private val RESPONSE_GET_MARKET_HISTORY = 1 - // The current conversion type - private var mConversionType: Short = -1 - - /* Variable used in the 2-step currency conversion, in order to temporally hold the value of the - * XXX -> BTS conversion. */ - private var coreCurrencyEqValue: AssetAmount? = null - - private var mDisposable: Disposable? = null + private var mDisposables = CompositeDisposable() /* Current user account */ private var mCurrentAccount: UserAccount? = null @@ -98,33 +81,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li /* Counter used to keep track of the transfer history batch count */ private var historicalTransferCount = 0 - /* List of block numbers with missing date information in the database */ - private var missingTimes: LinkedList? = null - - /* List of transactions for which we don't have the equivalent value data */ - private var missingEquivalentValues: LinkedList? = null - - /* Reference to the current operation entry that we're currently working with */ - private var mTransferEntry: HistoricalOperationEntry? = null - - /* Map used to exclude operation ids that were already checked for equivalent value, but could - * not be obtained for some reason. This is important in order to add some finality to the - * procedure - */ - private val eqValueBlacklist = HashMap() - -// /* -// * Account loader, used to fetch extra information about any new account that we might come -// * across after updating the transfers information -// */ -// private var missingAccountsLoader: MissingAccountsLoader? = null - -// /* -// * Assets loader, used to fetch missing asset data after the transfers table has been updated -// */ -// private var missingAssetsLoader: MissingAssetsLoader? = null - - // Used to keep track of the current state + // Used to keep track of the current state TODO this may not be needed private var mState = State.IDLE /** @@ -134,26 +91,9 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li private var lastId: Long = 0 - private var lastEquivalentValueBlockNum: Long = 0 - - private var lastMissingTimeBlockNum: Long = 0 - // Map used to keep track of request and response id pairs private val responseMap = HashMap() - private val mNetworkServiceConnection = object : ServiceConnection { - override fun onServiceConnected(className: ComponentName, service: IBinder) { - // We've bound to LocalService, cast the IBinder and get LocalService instance - val binder = service as NetworkService.LocalBinder - mNetworkService = binder.service - - // Start the transfers update - startTransfersUpdateProcedure() - } - - override fun onServiceDisconnected(componentName: ComponentName) {} - } - /** * Enum class used to keep track of the current state of the loader */ @@ -174,7 +114,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li val userId = pref.getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") if (userId != "") { mCurrentAccount = UserAccount(userId) - val disposable = authorityRepository!!.getWIF(userId!!, AuthorityType.MEMO.ordinal) + mDisposables.add(authorityRepository!!.getWIF(userId!!, AuthorityType.MEMO.ordinal) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { encryptedWIF -> @@ -184,8 +124,8 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li Log.e(TAG, "AEADBadTagException. Class: " + e.javaClass + ", Msg: " + e.message) } - } - mDisposable = RxBus.getBusInstance() + }) + mDisposables.add(RxBus.getBusInstance() .asFlowable() .observeOn(AndroidSchedulers.mainThread()) .subscribe(Consumer { message -> @@ -196,12 +136,9 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li val responseType = responseMap[message.id] when (responseType) { RESPONSE_GET_RELATIVE_ACCOUNT_HISTORY -> handleOperationList(message.result as List) -// RESPONSE_GET_MARKET_HISTORY -> handlePastMarketData(message.result as List) } responseMap.remove(message.id) } - } else if (message.result is BlockHeader) { -// handleMissingTimeResponse(message.result as BlockHeader) } } else if (message is ConnectionStatusUpdate) { if (message.updateCode == ConnectionStatusUpdate.DISCONNECTED) { @@ -209,24 +146,32 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li // all its stored request ids will now be reset responseMap.clear() } - // According to Nelson this is better than doing it in onServiceConnected, but here it does not get called -// else if (message.updateCode == ConnectionStatusUpdate.CONNECTED) { -// // Start the transfers update -// startTransfersUpdateProcedure() -// } } - }) + })) } else { // If there is no current user, we should not do anything mState = State.CANCELLED } } + override fun onServiceDisconnected(name: ComponentName?) { + + } + + override fun onServiceConnected(name: ComponentName?, service: IBinder?) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + val binder = service as NetworkService.LocalBinder + mNetworkService = binder.service + + // Start the transfers update + startTransfersUpdateProcedure() + } + @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) internal fun onStart() { if (mState != State.CANCELLED) { val intent = Intent(mContext, NetworkService::class.java) - if (mContext!!.bindService(intent, mNetworkServiceConnection, Context.BIND_AUTO_CREATE)) { + if (mContext!!.bindService(intent, this, Context.BIND_AUTO_CREATE)) { mShouldUnbindNetwork = true } else { Log.e(TAG, "Binding to the network service failed.") @@ -242,7 +187,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li // If we are in debug mode, we first erase all entries in the 'transfer' table transferRepository!!.deleteAll() } - val disposable = transferRepository!!.getCount() + mDisposables.add(transferRepository!!.getCount() .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe { transferCount -> @@ -253,7 +198,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li } // Retrieving account transactions loadNextOperationsBatch() - } + }) } /** @@ -270,26 +215,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li val insertedCount = transferRepository!!.insertAll(processOperationList(operationHistoryList)) // Log.d(TAG, String.format("Inserted count: %d, list size: %d", insertedCount, operationHistoryList.size)) if (/* insertedCount == 0 && */ operationHistoryList.isEmpty()) { - // We finally reached the end of the transactions, so now we must check for missing - // transfer times -// mState = State.LOADING_MISSING_TIMES -// missingTimes = database.getMissingTransferTimes(lastMissingTimeBlockNum, MISSING_TIMES_BATCH_SIZE) -// if (missingTimes!!.size > 0) { -// // Proceed to load missing times -// processNextMissingTime() -// } else { -// // If we got no missing times, proceed to check for missing equivalent values -// mState = State.LOADING_EQ_VALUES -// -// // If we're done loading missing transfer times, we check for missing equivalent values. -// missingEquivalentValues = database.getMissingEquivalentValues( -// lastEquivalentValueBlockNum, -// PalmPayDatabase.DEFAULT_EQUIVALENT_VALUE_BATCH_SIZE -// ) -// -// // Processing one of the missing values entries -// processNextEquivalentValue() -// } + // TODO Terminate process and obtain MissingTimes and MissingEquivalentValues } else { // If we inserted more than one operation, we cannot yet be sure we've reached the @@ -390,259 +316,12 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li return transfers } -// /** -// * Handles the response to the 'get_block_header' API call -// * @param blockHeader The requested block header -// */ -// private fun handleMissingTimeResponse(blockHeader: BlockHeader) { -// if (missingTimes == null || missingTimes!!.size == 0 || mState == State.CANCELLED) { -// // If the missingTimes attribute is null, this means that the request was probably issued -// // by another instance of this class. -// Log.d(TAG, "Cancelling loader instance") -// mState = State.CANCELLED -// return -// } -// val updated = database.setBlockTime(blockHeader, missingTimes!!.peek()) -// if (!updated) { -// Log.w(TAG, "Failed to update time from transaction at block: " + missingTimes!!.peek()) -// } else { -// Log.d(TAG, "Missing time updated") -// } -// -// // Removing missing time from stack -// lastMissingTimeBlockNum = missingTimes!!.poll() -// -// if (!processNextMissingTime()) { -// Log.d( -// TAG, -// String.format("Checking missing time for transfers later than block %d", lastMissingTimeBlockNum) -// ) -// missingTimes = database.getMissingTransferTimes(lastMissingTimeBlockNum, MISSING_TIMES_BATCH_SIZE) -// if (missingTimes!!.size == 0) { -// // If we have no more missing times to handle, we can finally proceed to the last step, which -// // is to take care of the missing equivalent values -// Log.d(TAG, "Would be trying to check equivalent values") -// // If we're done loading missing transfer times, we check for missing equivalent values. -// missingEquivalentValues = database.getMissingEquivalentValues( -// lastEquivalentValueBlockNum, -// PalmPayDatabase.DEFAULT_EQUIVALENT_VALUE_BATCH_SIZE -// ) -// -// // Processing one of the missing values entries -// processNextEquivalentValue() -// } else { -// processNextMissingTime() -// } -// } -// } - -// private fun processNextEquivalentValue() { -// if (missingEquivalentValues!!.size > 0) { -// Log.d(TAG, String.format("Found %d missing equivalent values", missingEquivalentValues!!.size)) -// val missingAssets = database.getMissingAssets() -// if (missingAssets.size == 0 && -// mTransferEntry != null && -// mTransferEntry!!.historicalTransfer!!.operation is TransferOperation -// ) { -// mTransferEntry = missingEquivalentValues!!.peek() -// lastEquivalentValueBlockNum = mTransferEntry!!.historicalTransfer!!.blockNum -// val transferOperation = mTransferEntry!!.historicalTransfer!!.operation as TransferOperation -// val transferredAsset = transferOperation.assetAmount.asset -// if (transferredAsset == Constants.bitUSD) { -// // Easier case, in which the transferred asset was already the designated -// // smartcoin (bitUSD) -// mTransferEntry!!.equivalentValue = AssetAmount( -// transferOperation.assetAmount.amount, -// transferredAsset -// ) -// database.updateEquivalentValue(mTransferEntry) -// -// // Removing the now solved equivalent value -// missingEquivalentValues!!.poll() -// -// // Processing the next missing equivalent value -// processNextEquivalentValue() -// } else if (transferredAsset == Constants.BTS) { -// // If the transferred asset was the core BTS currency, then we must just -// // perform a single network request to find out how much a single BTS was -// // worth at the time of this operation -// val quote = Constants.bitUSD -// val bucket: Long = 86400 -// val end = mTransferEntry!!.timestamp * 1000 -// val start = end - 86400 * 1000 -// lastId = mNetworkService!!.sendMessage( -// GetMarketHistory(transferredAsset, quote, bucket, start, end), -// GetMarketHistory.REQUIRED_API -// ) -// responseMap[lastId] = RESPONSE_GET_MARKET_HISTORY -// -// // Direct conversion -// mConversionType = DIRECT_CONVERSION -// } else { -// // If the transferred asset was not bitUSD not BTS, then we cannot be sure -// // that a market for this asset (which can either be a smartcoin or a User Issued Asset) -// // even exists. For this reason, we opt to convert this value to BTS first, and -// // then find out its equivalent value in bitUSD at the time of the transfer. -// Log.d(TAG, "Missing equivalent value was of other denomination") -// val quote = Constants.BTS -// val bucket: Long = 86400 -// val end = mTransferEntry!!.timestamp * 1000 -// val start = end - 86400 * 1000 -// lastId = mNetworkService!!.sendMessage( -// GetMarketHistory(transferredAsset, quote, bucket, start, end), -// GetMarketHistory.REQUIRED_API -// ) -// responseMap[lastId] = RESPONSE_GET_MARKET_HISTORY -// -// // Indirect conversion -// mConversionType = INDIRECT_CONVERSION -// } -// } -// } else { -// Log.d(TAG, "Reached the end of the equivalent values stack") -// missingEquivalentValues = database.getMissingEquivalentValues( -// lastEquivalentValueBlockNum, -// PalmPayDatabase.DEFAULT_EQUIVALENT_VALUE_BATCH_SIZE -// ) -// -// Log.d(TAG, String.format("Got %d entries initially", missingEquivalentValues!!.size)) -// -// // Clearing the equivalent values stack from blacklisted item -// for (i in missingEquivalentValues!!.indices) { -// val entry = missingEquivalentValues!!.peek() -// if (eqValueBlacklist[entry.historicalTransfer!!.objectId] != null) { -// // Removing this equivalent value from the stack, since we've already tried to solve it -// missingEquivalentValues!!.poll() -// -// Log.d(TAG, "Removed entry from stack thanks to the black list") -// } -// } -// -// if (missingEquivalentValues!!.size > 0) { -// Log.d(TAG, "Got a new stack") -// processNextEquivalentValue() -// } else { -// Log.d(TAG, "Really reached the final") -//// missingAssetsLoader = MissingAssetsLoader(mContext, mLifeCycle) -//// missingAccountsLoader = MissingAccountsLoader(mContext!!, mLifeCycle) -// mState = State.FINISHED -// } -// } -// } - -// /** -// * Handle the requested past market data, in order to calculate the equivalent value -// * @param buckets List of market buckets -// */ -// private fun handlePastMarketData(buckets: List) { -// if (buckets.isNotEmpty()) { -// // Taking the last bucket from the list -// val bucket = buckets[buckets.size - 1] -// -// // Obtaining the transferred amount -// val transferAmount = -// (mTransferEntry!!.historicalTransfer!!.operation as TransferOperation).assetAmount -// -// // Obtaining the full asset data of both base and quote -// var base = database.fillAssetDetails(bucket.key.base) -// var quote = database.fillAssetDetails(bucket.key.quote) -// if (mConversionType == DIRECT_CONVERSION) { -// // Doing conversion and updating the database -// val converter = Converter(base, quote, bucket) -// val convertedBaseValue = converter.convert(transferAmount, Converter.CLOSE_VALUE) -// val equivalentValue = AssetAmount(UnsignedLong.valueOf(convertedBaseValue), Constants.bitUSD) -// -// mTransferEntry!!.equivalentValue = equivalentValue -// database.updateEquivalentValue(mTransferEntry) -// -// // Removing the now solved equivalent value -// missingEquivalentValues!!.poll() -// -// // Process the next equivalent value, in case we have one -// processNextEquivalentValue() -// } else if (mConversionType == INDIRECT_CONVERSION) { -// if (coreCurrencyEqValue == null) { -// // We are in the first step of an indirect conversion -// -// val originalTransfer = -// (mTransferEntry!!.historicalTransfer!!.operation as TransferOperation).assetAmount -// -// // Doing conversion and updating the database -// val converter = Converter(base, quote, bucket) -// val convertedBaseValue = converter.convert(originalTransfer, Converter.CLOSE_VALUE) -// coreCurrencyEqValue = AssetAmount(UnsignedLong.valueOf(convertedBaseValue), base) -// -// base = database.fillAssetDetails(Constants.BTS) -// quote = database.fillAssetDetails(Constants.bitUSD) -// -// // Performing the 2nd step of the equivalent value calculation. We already hold the -// // relationship XXX -> BTS, now we need the BTS -> bitUSD for this time bucket. -// val bucketWindow: Long = 86400 -// val end = mTransferEntry!!.timestamp * 1000 -// val start = end - 86400 * 1000 -// lastId = mNetworkService!!.sendMessage( -// GetMarketHistory(base, quote, bucketWindow, start, end), -// GetMarketHistory.REQUIRED_API -// ) -// responseMap[lastId] = RESPONSE_GET_MARKET_HISTORY -// } else { -// // We are in the second step of an indirect transaction -// -// // Doing the conversion -// val converter = Converter(base, quote, bucket) -// val convertedFinalValue = converter.convert(coreCurrencyEqValue, Converter.CLOSE_VALUE) -// -// // Obtaining the equivalent value in bitUSD -// val equivalentValue = AssetAmount(UnsignedLong.valueOf(convertedFinalValue), Constants.bitUSD) -// -// mTransferEntry!!.equivalentValue = equivalentValue -// database.updateEquivalentValue(mTransferEntry) -// -// // Removing the now solved equivalent value -// missingEquivalentValues!!.poll() -// -// // Re-setting some fields -// mConversionType = -1 -// coreCurrencyEqValue = null -// -// // Process the next equivalent value, in case we have one -// processNextEquivalentValue() -// } -// } -// } else { -// // Removing the for-now skipped equivalent value -// val skipped = missingEquivalentValues!!.poll() -// -// // Adding the skipped operation to a blacklist -// eqValueBlacklist[skipped.historicalTransfer!!.objectId] = true -// -// Log.w(TAG, "Got no buckets in the selected period") -// processNextEquivalentValue() -// } -// } - -// /** -// * Method used to issue a new 'get_block_header' API call to the full node, in case we -// * still have some missing times left in the missingTimes list. -// * -// * @return True if we did issue the API, false if the list was empty and nothing was done -// */ -// private fun processNextMissingTime(): Boolean { -// if (missingTimes!!.size > 0) { -// val blockNum = missingTimes!!.peek() -// lastId = mNetworkService!!.sendMessage(GetBlockHeader(blockNum!!), GetBlockHeader.REQUIRED_API) -// return true -// } else { -// return false -// } -// } - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) internal fun onDestroy() { Log.d(TAG, "Destroying TransfersLoader") - if (mDisposable != null && !mDisposable!!.isDisposed) mDisposable!!.dispose() + if (!mDisposables.isDisposed) mDisposables.dispose() if (mShouldUnbindNetwork) { - mContext!!.unbindService(mNetworkServiceConnection) + mContext!!.unbindService(this) mShouldUnbindNetwork = false } mContext = null From 51363bdf005989694ee2e2197fb02b29babaaaba Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 28 Nov 2018 20:13:40 -0600 Subject: [PATCH 033/129] - Create basic TransactionsAdapter to populate the Transactions RecyclerView in Balances. - Create basic Transactions items layout. --- .../activities/MainActivity.kt | 2 +- .../adapters/TransactionsAdapter.kt | 118 +++++++++++ .../fragments/BalancesFragment.kt | 18 ++ .../processors/TransfersLoader.kt | 2 +- .../repositories/TransferRepository.kt | 5 + .../viewmodels/TransactionViewModel.kt | 15 ++ .../main/res/drawable/ic_arrow_receive.xml | 10 + app/src/main/res/drawable/ic_arrow_send.xml | 10 + app/src/main/res/layout/item_transaction.xml | 199 +++++++++++++++++- app/src/main/res/values/colors.xml | 3 + 10 files changed, 371 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt create mode 100644 app/src/main/res/drawable/ic_arrow_receive.xml create mode 100644 app/src/main/res/drawable/ic_arrow_send.xml diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 6ba72d6..2824123 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -17,7 +17,7 @@ import cy.agorise.graphenej.models.JsonRpcResponse import kotlinx.android.synthetic.main.activity_main.* class MainActivity : ConnectedActivity() { - private val TAG = this.javaClass.name + private val TAG = this.javaClass.simpleName private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> when (item.itemId) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt new file mode 100644 index 0000000..e3d5db7 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt @@ -0,0 +1,118 @@ +package cy.agorise.bitsybitshareswallet.adapters + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.SortedList +import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.entities.Transfer + +class TransactionsAdapter(private val context: Context, private val mComparator: Comparator) : + RecyclerView.Adapter() { + + private val mSortedList = + SortedList(Transfer::class.java, object : SortedList.Callback() { + override fun onInserted(position: Int, count: Int) { + notifyItemRangeInserted(position, count) + } + + override fun onRemoved(position: Int, count: Int) { + notifyItemRangeRemoved(position, count) + } + + override fun onMoved(fromPosition: Int, toPosition: Int) { + notifyItemMoved(fromPosition, toPosition) + } + + override fun onChanged(position: Int, count: Int) { + notifyItemRangeChanged(position, count) + } + + override fun compare(a: Transfer, b: Transfer): Int { + return mComparator.compare(a, b) + } + + override fun areContentsTheSame(oldItem: Transfer, newItem: Transfer): Boolean { + return oldItem == newItem + } + + override fun areItemsTheSame(item1: Transfer, item2: Transfer): Boolean { + return item1.id == item2.id + } + }) + + inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val rootView = itemView.findViewById(R.id.rootView) + val vPaymentDirection = itemView.findViewById(R.id.vPaymentDirection) + val tvFrom = itemView.findViewById(R.id.tvFrom) + val ivDirectionArrow = itemView.findViewById(R.id.ivDirectionArrow) + val tvTo = itemView.findViewById(R.id.tvTo) + val llMemo = itemView.findViewById(R.id.llMemo) + val tvMemo = itemView.findViewById(R.id.tvMemo) + val tvDate = itemView.findViewById(R.id.tvDate) + val tvTime = itemView.findViewById(R.id.tvTime) + val tvCryptoAmount = itemView.findViewById(R.id.tvCryptoAmount) + val tvFiatEquivalent = itemView.findViewById(R.id.tvFiatEquivalent) + } + + init { + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionsAdapter.ViewHolder { + val inflater = LayoutInflater.from(context) + + val transactionView = inflater.inflate(R.layout.item_transaction, parent, false) + + return ViewHolder(transactionView) + } + + override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { + val transaction = mSortedList.get(position) + + viewHolder.tvFrom.text = transaction.source + viewHolder.tvTo.text = transaction.destination + } + + fun add(transaction: Transfer) { + mSortedList.add(transaction) + } + + fun remove(transaction: Transfer) { + mSortedList.remove(transaction) + } + + fun add(transactions: List) { + mSortedList.addAll(transactions) + } + + fun remove(transactions: List) { + mSortedList.beginBatchedUpdates() + for (transaction in transactions) { + mSortedList.remove(transaction) + } + mSortedList.endBatchedUpdates() + } + + fun replaceAll(transactions: List) { + mSortedList.beginBatchedUpdates() + for (i in mSortedList.size() - 1 downTo 0) { + val transaction = mSortedList.get(i) + if (!transactions.contains(transaction)) { + mSortedList.remove(transaction) + } + } + mSortedList.addAll(transactions) + mSortedList.endBatchedUpdates() + } + + override fun getItemCount(): Int { + return mSortedList.size() + } +} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index 77469c2..db4b1f3 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -8,18 +8,27 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.lifecycle.Observer +import androidx.recyclerview.widget.LinearLayoutManager import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.adapters.TransactionsAdapter +import cy.agorise.bitsybitshareswallet.entities.Transfer import cy.agorise.bitsybitshareswallet.entities.UserAccount import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.viewmodels.BalancesViewModel +import cy.agorise.bitsybitshareswallet.viewmodels.TransactionViewModel import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel import kotlinx.android.synthetic.main.fragment_balances.* +import java.util.Comparator class BalancesFragment : Fragment() { private lateinit var mUserAccountViewModel: UserAccountViewModel private lateinit var mBalancesViewModel: BalancesViewModel + private lateinit var mTransactionViewModel: TransactionViewModel + + private val mComparator = + Comparator { a, b -> a.id.compareTo(b.id) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -44,5 +53,14 @@ class BalancesFragment : Fragment() { mBalancesViewModel = ViewModelProviders.of(this).get(BalancesViewModel::class.java) // TODO: Use the ViewModel + mTransactionViewModel = ViewModelProviders.of(this).get(TransactionViewModel::class.java) + + val transactionsAdapter = TransactionsAdapter(context!!, mComparator) + rvTransactions.adapter = transactionsAdapter + rvTransactions.layoutManager = LinearLayoutManager(context) + + mTransactionViewModel.getAll().observe(this, Observer> { transfers -> + transactionsAdapter.replaceAll(transfers) + }) } } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt index df93fad..11cf6f2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt @@ -51,7 +51,7 @@ import javax.crypto.AEADBadTagException class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Lifecycle) : LifecycleObserver, ServiceConnection { - private val TAG = this.javaClass.name + private val TAG = this.javaClass.simpleName /** Constant that specifies if we are on debug mode */ private val DEBUG = false diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt index 821d754..361a61e 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt @@ -2,6 +2,7 @@ package cy.agorise.bitsybitshareswallet.repositories import android.content.Context import android.os.AsyncTask +import androidx.lifecycle.LiveData import cy.agorise.bitsybitshareswallet.daos.BitsyDatabase import cy.agorise.bitsybitshareswallet.daos.TransferDao import cy.agorise.bitsybitshareswallet.entities.Transfer @@ -20,6 +21,10 @@ class TransferRepository internal constructor(context: Context) { insertAllAsyncTask(mTransferDao).execute(transfers) } + fun getAll(): LiveData> { + return mTransferDao.getAll() + } + fun getCount(): Single { return mTransferDao.getCount() } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt new file mode 100644 index 0000000..f489b8e --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt @@ -0,0 +1,15 @@ +package cy.agorise.bitsybitshareswallet.viewmodels + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import cy.agorise.bitsybitshareswallet.entities.Transfer +import cy.agorise.bitsybitshareswallet.repositories.TransferRepository + +class TransactionViewModel(application: Application) : AndroidViewModel(application) { + private var mRepository = TransferRepository(application) + + internal fun getAll(): LiveData> { + return mRepository.getAll() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_receive.xml b/app/src/main/res/drawable/ic_arrow_receive.xml new file mode 100644 index 0000000..4f68029 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_receive.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_send.xml b/app/src/main/res/drawable/ic_arrow_send.xml new file mode 100644 index 0000000..5628630 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_send.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_transaction.xml b/app/src/main/res/layout/item_transaction.xml index f818652..c042a15 100644 --- a/app/src/main/res/layout/item_transaction.xml +++ b/app/src/main/res/layout/item_transaction.xml @@ -1,14 +1,195 @@ - + android:layout_height="wrap_content" + android:layout_gravity="center" + card_view:cardElevation="4dp" + card_view:cardCornerRadius="4dp" + android:layout_margin="4dp"> - + android:clickable="true" + android:focusable="true" + android:foreground="?android:attr/selectableItemBackground"> - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f0506dc..411afcc 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -6,4 +6,7 @@ #000 #888 + #e0e0e0 + #669900 + #DC473A
From fc98208c30c0fb75c42d3448b6ab745a008e30a2 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 28 Nov 2018 21:52:00 -0600 Subject: [PATCH 034/129] - Add method to update account balances. - Create BalancesRepository to handle Balances related db operations. --- .../activities/MainActivity.kt | 58 ++++++++++++++++++- .../bitsybitshareswallet/daos/BalanceDao.kt | 6 +- .../repositories/BalanceRepository.kt | 35 +++++++++++ 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceRepository.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 2824123..75b753b 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -2,23 +2,40 @@ package cy.agorise.bitsybitshareswallet.activities import android.content.Intent import android.os.Bundle +import android.preference.PreferenceManager import android.util.Log import android.view.Menu import android.view.MenuItem import android.widget.Toast +import androidx.collection.LongSparseArray import com.google.android.material.bottomnavigation.BottomNavigationView import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.entities.Balance import cy.agorise.bitsybitshareswallet.fragments.BalancesFragment import cy.agorise.bitsybitshareswallet.fragments.MerchantsFragment import cy.agorise.bitsybitshareswallet.processors.TransfersLoader +import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository +import cy.agorise.bitsybitshareswallet.utils.Constants +import cy.agorise.graphenej.AssetAmount +import cy.agorise.graphenej.RPC +import cy.agorise.graphenej.UserAccount import cy.agorise.graphenej.api.ApiAccess import cy.agorise.graphenej.api.ConnectionStatusUpdate +import cy.agorise.graphenej.api.calls.GetAccountBalances import cy.agorise.graphenej.models.JsonRpcResponse import kotlinx.android.synthetic.main.activity_main.* +import java.util.ArrayList class MainActivity : ConnectedActivity() { private val TAG = this.javaClass.simpleName + private val requestMap = LongSparseArray() + + /* Current user account */ + private var mCurrentAccount: UserAccount? = null + + private var mBalanceRepository: BalanceRepository? = null + private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> when (item.itemId) { R.id.navigation_receive -> { @@ -47,6 +64,13 @@ class MainActivity : ConnectedActivity() { navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) navigation.selectedItemId = R.id.navigation_balances + + val userId = PreferenceManager.getDefaultSharedPreferences(this) + .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") + if (userId != "") + mCurrentAccount = UserAccount(userId) + + mBalanceRepository = BalanceRepository(this) } private fun loadBalancesFragment() { @@ -79,7 +103,9 @@ class MainActivity : ConnectedActivity() { } override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) { - + if (requestMap.get(response.id) == RPC.CALL_GET_ACCOUNT_BALANCES) { + handleBalanceUpdate(response as JsonRpcResponse>) + } } /** @@ -100,8 +126,38 @@ class MainActivity : ConnectedActivity() { Log.d(TAG, "ConnectionStatusUpdate: API_NETWORK_BROADCAST") // Instantiating this loader is enough to kick-start the transfers loading procedure TransfersLoader(this, lifecycle) + + updateBalances() } } } } + + private fun updateBalances() { + if (mNetworkService!!.isConnected) { + val id = mNetworkService!!.sendMessage( + GetAccountBalances(mCurrentAccount, ArrayList()), + GetAccountBalances.REQUIRED_API + ) + requestMap.put(id, RPC.CALL_GET_ACCOUNT_BALANCES) + } + } + + private fun handleBalanceUpdate(response: JsonRpcResponse>) { + Log.d(TAG, "handleBalanceUpdate") + val now = System.currentTimeMillis() / 1000 + val assetBalances = response.result + val balances = ArrayList() + for (assetBalance in assetBalances) { + val balance = Balance( + mCurrentAccount!!.objectId, + assetBalance.asset.objectId, + assetBalance.amount.toLong(), + now + ) + + balances.add(balance) + } + mBalanceRepository!!.insertAll(balances) + } } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt index 222f9f8..277b14c 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt @@ -3,6 +3,7 @@ package cy.agorise.bitsybitshareswallet.daos import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert +import androidx.room.OnConflictStrategy import androidx.room.Query import cy.agorise.bitsybitshareswallet.entities.Balance @@ -11,6 +12,9 @@ interface BalanceDao { @Insert fun insert(balance: Balance) + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertAll(balances: List) + @Query("SELECT * FROM balances") - fun getAllBalances(): LiveData> + fun getAll(): LiveData> } \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceRepository.kt new file mode 100644 index 0000000..201979c --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceRepository.kt @@ -0,0 +1,35 @@ +package cy.agorise.bitsybitshareswallet.repositories + +import android.content.Context +import android.os.AsyncTask +import androidx.lifecycle.LiveData +import cy.agorise.bitsybitshareswallet.daos.BalanceDao +import cy.agorise.bitsybitshareswallet.daos.BitsyDatabase +import cy.agorise.bitsybitshareswallet.entities.Balance + +class BalanceRepository internal constructor(context: Context) { + + private val mBalanceDao: BalanceDao + + init { + val db = BitsyDatabase.getDatabase(context) + mBalanceDao = db!!.balanceDao() + } + + fun insertAll(balances: List) { + insertAllAsyncTask(mBalanceDao).execute(balances) + } + + fun getAll(): LiveData> { + return mBalanceDao.getAll() + } + + private class insertAllAsyncTask internal constructor(private val mAsyncTaskDao: BalanceDao) : + AsyncTask, Void, Void>() { + + override fun doInBackground(vararg transfers: List): Void? { + mAsyncTaskDao.insertAll(transfers[0]) + return null + } + } +} \ No newline at end of file From dd770fdb5bef9d153fe135e410bbd451b917488b Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Sat, 1 Dec 2018 08:48:19 -0600 Subject: [PATCH 035/129] - Created Balances adapter and ViewModel to show the Account Balances in the BalancesFragment. - Simplified the Balances db table. --- .../activities/MainActivity.kt | 1 - .../adapters/BalancesAdapter.kt | 104 ++++++++++++++++++ .../adapters/TransactionsAdapter.kt | 31 +++--- .../bitsybitshareswallet/entities/Balance.kt | 8 +- .../fragments/BalancesFragment.kt | 26 +++-- .../viewmodels/BalanceViewModel.kt | 16 +++ .../viewmodels/BalancesViewModel.kt | 8 -- 7 files changed, 156 insertions(+), 38 deletions(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt delete mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalancesViewModel.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 75b753b..202f60e 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -150,7 +150,6 @@ class MainActivity : ConnectedActivity() { val balances = ArrayList() for (assetBalance in assetBalances) { val balance = Balance( - mCurrentAccount!!.objectId, assetBalance.asset.objectId, assetBalance.amount.toLong(), now diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt new file mode 100644 index 0000000..dc2ad19 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt @@ -0,0 +1,104 @@ +package cy.agorise.bitsybitshareswallet.adapters + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.SortedList +import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.entities.Balance + +class BalancesAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val mComparator = + Comparator { a, b -> a.assetId.compareTo(b.assetId) } + + private val mSortedList = + SortedList(Balance::class.java, object : SortedList.Callback() { + override fun onInserted(position: Int, count: Int) { + notifyItemRangeInserted(position, count) + } + + override fun onRemoved(position: Int, count: Int) { + notifyItemRangeRemoved(position, count) + } + + override fun onMoved(fromPosition: Int, toPosition: Int) { + notifyItemMoved(fromPosition, toPosition) + } + + override fun onChanged(position: Int, count: Int) { + notifyItemRangeChanged(position, count) + } + + override fun compare(a: Balance, b: Balance): Int { + return mComparator.compare(a, b) + } + + override fun areContentsTheSame(oldItem: Balance, newItem: Balance): Boolean { + return oldItem == newItem + } + + override fun areItemsTheSame(item1: Balance, item2: Balance): Boolean { + return item1.assetId == item2.assetId + } + }) + + inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val tvBalance: TextView = itemView.findViewById(R.id.tvBalance) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BalancesAdapter.ViewHolder { + val inflater = LayoutInflater.from(context) + + val balanceView = inflater.inflate(R.layout.item_balance, parent, false) + + return ViewHolder(balanceView) + } + + override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { + val balance = mSortedList.get(position) + + val amount = "${balance.assetAmount} ${balance.assetId}" + viewHolder.tvBalance.text = amount + } + + fun add(balance: Balance) { + mSortedList.add(balance) + } + + fun remove(balance: Balance) { + mSortedList.remove(balance) + } + + fun add(balances: List) { + mSortedList.addAll(balances) + } + + fun remove(balances: List) { + mSortedList.beginBatchedUpdates() + for (balance in balances) { + mSortedList.remove(balance) + } + mSortedList.endBatchedUpdates() + } + + fun replaceAll(balances: List) { + mSortedList.beginBatchedUpdates() + for (i in mSortedList.size() - 1 downTo 0) { + val balance = mSortedList.get(i) + if (!balances.contains(balance)) { + mSortedList.remove(balance) + } + } + mSortedList.addAll(balances) + mSortedList.endBatchedUpdates() + } + + override fun getItemCount(): Int { + return mSortedList.size() + } +} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt index e3d5db7..dc70930 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt @@ -13,9 +13,12 @@ import androidx.recyclerview.widget.SortedList import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.entities.Transfer -class TransactionsAdapter(private val context: Context, private val mComparator: Comparator) : +class TransactionsAdapter(private val context: Context) : RecyclerView.Adapter() { + private val mComparator = + Comparator { a, b -> a.id.compareTo(b.id) } + private val mSortedList = SortedList(Transfer::class.java, object : SortedList.Callback() { override fun onInserted(position: Int, count: Int) { @@ -48,21 +51,17 @@ class TransactionsAdapter(private val context: Context, private val mComparator: }) inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - val rootView = itemView.findViewById(R.id.rootView) - val vPaymentDirection = itemView.findViewById(R.id.vPaymentDirection) - val tvFrom = itemView.findViewById(R.id.tvFrom) - val ivDirectionArrow = itemView.findViewById(R.id.ivDirectionArrow) - val tvTo = itemView.findViewById(R.id.tvTo) - val llMemo = itemView.findViewById(R.id.llMemo) - val tvMemo = itemView.findViewById(R.id.tvMemo) - val tvDate = itemView.findViewById(R.id.tvDate) - val tvTime = itemView.findViewById(R.id.tvTime) - val tvCryptoAmount = itemView.findViewById(R.id.tvCryptoAmount) - val tvFiatEquivalent = itemView.findViewById(R.id.tvFiatEquivalent) - } - - init { - + val rootView: ConstraintLayout = itemView.findViewById(R.id.rootView) + val vPaymentDirection: View = itemView.findViewById(R.id.vPaymentDirection) + val tvFrom: TextView = itemView.findViewById(R.id.tvFrom) + val ivDirectionArrow: ImageView = itemView.findViewById(R.id.ivDirectionArrow) + val tvTo: TextView = itemView.findViewById(R.id.tvTo) + val llMemo: LinearLayout = itemView.findViewById(R.id.llMemo) + val tvMemo: TextView = itemView.findViewById(R.id.tvMemo) + val tvDate: TextView = itemView.findViewById(R.id.tvDate) + val tvTime: TextView = itemView.findViewById(R.id.tvTime) + val tvCryptoAmount: TextView = itemView.findViewById(R.id.tvCryptoAmount) + val tvFiatEquivalent: TextView = itemView.findViewById(R.id.tvFiatEquivalent) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionsAdapter.ViewHolder { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Balance.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Balance.kt index d51eca2..be42d04 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Balance.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Balance.kt @@ -2,12 +2,12 @@ package cy.agorise.bitsybitshareswallet.entities import androidx.room.ColumnInfo import androidx.room.Entity +import androidx.room.PrimaryKey -@Entity(tableName = "balances", primaryKeys = ["user_account_id", "asset_id"]) -// TODO make userAccountId and assetId be ForeignKeys +@Entity(tableName = "balances") data class Balance( - @ColumnInfo(name = "user_account_id") val userAccountId: String, - @ColumnInfo(name = "asset_id") val assetId: String, + @PrimaryKey + @ColumnInfo(name = "asset_id") val assetId: String, // TODO should be foreign key? @ColumnInfo(name = "asset_amount") val assetAmount: Long, @ColumnInfo(name = "last_update") val lastUpdate: Long ) \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index db4b1f3..8da9ba0 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -8,28 +8,27 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.lifecycle.Observer +import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.adapters.BalancesAdapter import cy.agorise.bitsybitshareswallet.adapters.TransactionsAdapter +import cy.agorise.bitsybitshareswallet.entities.Balance import cy.agorise.bitsybitshareswallet.entities.Transfer import cy.agorise.bitsybitshareswallet.entities.UserAccount import cy.agorise.bitsybitshareswallet.utils.Constants -import cy.agorise.bitsybitshareswallet.viewmodels.BalancesViewModel +import cy.agorise.bitsybitshareswallet.viewmodels.BalanceViewModel import cy.agorise.bitsybitshareswallet.viewmodels.TransactionViewModel import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel import kotlinx.android.synthetic.main.fragment_balances.* -import java.util.Comparator class BalancesFragment : Fragment() { private lateinit var mUserAccountViewModel: UserAccountViewModel - private lateinit var mBalancesViewModel: BalancesViewModel + private lateinit var mBalanceViewModel: BalanceViewModel private lateinit var mTransactionViewModel: TransactionViewModel - private val mComparator = - Comparator { a, b -> a.id.compareTo(b.id) } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -40,6 +39,7 @@ class BalancesFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + // Configure UserAccountViewModel to show the current account mUserAccountViewModel = ViewModelProviders.of(this).get(UserAccountViewModel::class.java) val userId = PreferenceManager.getDefaultSharedPreferences(context) @@ -49,13 +49,21 @@ class BalancesFragment : Fragment() { tvAccountName.text = user.name }) + // Configure BalanceViewModel to show the current balances + mBalanceViewModel = ViewModelProviders.of(this).get(BalanceViewModel::class.java) - mBalancesViewModel = ViewModelProviders.of(this).get(BalancesViewModel::class.java) - // TODO: Use the ViewModel + val balancesAdapter = BalancesAdapter(context!!) + rvBalances.adapter = balancesAdapter + rvBalances.layoutManager = GridLayoutManager(context, 2) + mBalanceViewModel.getAll().observe(this, Observer> { balances -> + balancesAdapter.replaceAll(balances) + }) + + // Configure TransactionViewModel to show the transaction history mTransactionViewModel = ViewModelProviders.of(this).get(TransactionViewModel::class.java) - val transactionsAdapter = TransactionsAdapter(context!!, mComparator) + val transactionsAdapter = TransactionsAdapter(context!!) rvTransactions.adapter = transactionsAdapter rvTransactions.layoutManager = LinearLayoutManager(context) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt new file mode 100644 index 0000000..5949a78 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt @@ -0,0 +1,16 @@ +package cy.agorise.bitsybitshareswallet.viewmodels + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import cy.agorise.bitsybitshareswallet.entities.Balance +import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository + + +class BalanceViewModel(application: Application) : AndroidViewModel(application) { + private var mRepository = BalanceRepository(application) + + internal fun getAll(): LiveData> { + return mRepository.getAll() + } +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalancesViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalancesViewModel.kt deleted file mode 100644 index 2b660b0..0000000 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalancesViewModel.kt +++ /dev/null @@ -1,8 +0,0 @@ -package cy.agorise.bitsybitshareswallet.viewmodels - -import android.app.Application -import androidx.lifecycle.AndroidViewModel - - -class BalancesViewModel(application: Application) : AndroidViewModel(application) { -} \ No newline at end of file From 5ec8afbdb311e6943dd166ca0509d173475dedbb Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Sat, 1 Dec 2018 09:25:25 -0600 Subject: [PATCH 036/129] Provide a better package structure for Room database related files. --- .../activities/DatabaseLoadActivity.kt | 4 ++-- .../activities/ImportBrainkeyActivity.kt | 4 ++-- .../activities/MainActivity.kt | 2 +- .../adapters/BalancesAdapter.kt | 2 +- .../adapters/TransactionsAdapter.kt | 2 +- .../{daos => database}/BitsyDatabase.kt | 20 ++++++++++--------- .../{ => database}/daos/AssetDao.kt | 4 ++-- .../{ => database}/daos/AuthorityDao.kt | 4 ++-- .../{ => database}/daos/BalanceDao.kt | 4 ++-- .../{ => database}/daos/EquivalentValueDao.kt | 4 ++-- .../{ => database}/daos/TransferDao.kt | 4 ++-- .../{ => database}/daos/UserAccountDao.kt | 4 ++-- .../{ => database}/entities/Asset.kt | 2 +- .../{ => database}/entities/Authority.kt | 2 +- .../{ => database}/entities/Balance.kt | 2 +- .../entities/EquivalentValue.kt | 2 +- .../{ => database}/entities/Transfer.kt | 2 +- .../{ => database}/entities/UserAccount.kt | 2 +- .../fragments/BalancesFragment.kt | 6 +++--- .../processors/TransfersLoader.kt | 2 +- .../repositories/AssetRepository.kt | 6 +++--- .../repositories/AuthorityRepository.kt | 6 +++--- .../repositories/BalanceRepository.kt | 6 +++--- .../repositories/TransferRepository.kt | 6 +++--- .../repositories/UserAccountRepository.kt | 6 +++--- .../viewmodels/BalanceViewModel.kt | 2 +- .../viewmodels/TransactionViewModel.kt | 2 +- .../viewmodels/UserAccountViewModel.kt | 2 +- 28 files changed, 58 insertions(+), 56 deletions(-) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{daos => database}/BitsyDatabase.kt (75%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/daos/AssetDao.kt (77%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/daos/AuthorityDao.kt (80%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/daos/BalanceDao.kt (77%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/daos/EquivalentValueDao.kt (72%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/daos/TransferDao.kt (84%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/daos/UserAccountDao.kt (77%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/entities/Asset.kt (88%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/entities/Authority.kt (90%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/entities/Balance.kt (86%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/entities/EquivalentValue.kt (92%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/entities/Transfer.kt (94%) rename app/src/main/java/cy/agorise/bitsybitshareswallet/{ => database}/entities/UserAccount.kt (84%) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/DatabaseLoadActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/DatabaseLoadActivity.kt index 3da27ad..d429788 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/DatabaseLoadActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/DatabaseLoadActivity.kt @@ -89,11 +89,11 @@ class DatabaseLoadActivity: ConnectedActivity() { * @param assetList The list of assets obtained in the last 'list_assets' API call. */ private fun handlePlatformAssetBatch(assetList: List) { - val assets = mutableListOf() + val assets = mutableListOf() // TODO find if there is a better way to convert to Bitsy Asset instances for (_asset in assetList) { - val asset = cy.agorise.bitsybitshareswallet.entities.Asset( + val asset = cy.agorise.bitsybitshareswallet.database.entities.Asset( _asset.objectId, _asset.symbol, _asset.precision, diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ImportBrainkeyActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ImportBrainkeyActivity.kt index 23abe45..da16885 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ImportBrainkeyActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ImportBrainkeyActivity.kt @@ -9,7 +9,7 @@ import android.widget.Toast import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.list.listItemsSingleChoice import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.entities.Authority +import cy.agorise.bitsybitshareswallet.database.entities.Authority import cy.agorise.bitsybitshareswallet.repositories.AuthorityRepository import cy.agorise.bitsybitshareswallet.repositories.UserAccountRepository import cy.agorise.bitsybitshareswallet.utils.Constants @@ -235,7 +235,7 @@ class ImportBrainkeyActivity : ConnectedActivity() { val name = accountProperties.name val isLTM = accountProperties.membership_expiration_date == Constants.LIFETIME_EXPIRATION_DATE - val userAccount = cy.agorise.bitsybitshareswallet.entities.UserAccount(id, name, isLTM) + val userAccount = cy.agorise.bitsybitshareswallet.database.entities.UserAccount(id, name, isLTM) val userAccountRepository = UserAccountRepository(application) userAccountRepository.insert(userAccount) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 202f60e..7ba4517 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -10,7 +10,7 @@ import android.widget.Toast import androidx.collection.LongSparseArray import com.google.android.material.bottomnavigation.BottomNavigationView import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.entities.Balance +import cy.agorise.bitsybitshareswallet.database.entities.Balance import cy.agorise.bitsybitshareswallet.fragments.BalancesFragment import cy.agorise.bitsybitshareswallet.fragments.MerchantsFragment import cy.agorise.bitsybitshareswallet.processors.TransfersLoader diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt index dc2ad19..47a1d57 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt @@ -8,7 +8,7 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SortedList import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.entities.Balance +import cy.agorise.bitsybitshareswallet.database.entities.Balance class BalancesAdapter(private val context: Context) : RecyclerView.Adapter() { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt index dc70930..cf9d490 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt @@ -11,7 +11,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SortedList import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.entities.Transfer +import cy.agorise.bitsybitshareswallet.database.entities.Transfer class TransactionsAdapter(private val context: Context) : RecyclerView.Adapter() { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt similarity index 75% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt index c0e965c..fc5205a 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt @@ -1,19 +1,21 @@ -package cy.agorise.bitsybitshareswallet.daos +package cy.agorise.bitsybitshareswallet.database import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase -import cy.agorise.bitsybitshareswallet.entities.* +import cy.agorise.bitsybitshareswallet.database.daos.* +import cy.agorise.bitsybitshareswallet.database.entities.* @Database(entities = [ - Asset::class, - Authority::class, - Balance::class, - EquivalentValue::class, - Transfer::class, - UserAccount::class - ], version = 1, exportSchema = false) + Asset::class, + Authority::class, + Balance::class, + EquivalentValue::class, + Transfer::class, + UserAccount::class + ], + version = 1, exportSchema = false) abstract class BitsyDatabase : RoomDatabase() { abstract fun assetDao(): AssetDao diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AssetDao.kt similarity index 77% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AssetDao.kt index 89c88f8..03a0eaa 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AssetDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AssetDao.kt @@ -1,11 +1,11 @@ -package cy.agorise.bitsybitshareswallet.daos +package cy.agorise.bitsybitshareswallet.database.daos import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import cy.agorise.bitsybitshareswallet.entities.Asset +import cy.agorise.bitsybitshareswallet.database.entities.Asset @Dao interface AssetDao { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AuthorityDao.kt similarity index 80% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AuthorityDao.kt index b17b2da..5956e15 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/AuthorityDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AuthorityDao.kt @@ -1,10 +1,10 @@ -package cy.agorise.bitsybitshareswallet.daos +package cy.agorise.bitsybitshareswallet.database.daos import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.Query -import cy.agorise.bitsybitshareswallet.entities.Authority +import cy.agorise.bitsybitshareswallet.database.entities.Authority import io.reactivex.Single @Dao diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/BalanceDao.kt similarity index 77% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/BalanceDao.kt index 277b14c..13826bd 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/BalanceDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/BalanceDao.kt @@ -1,11 +1,11 @@ -package cy.agorise.bitsybitshareswallet.daos +package cy.agorise.bitsybitshareswallet.database.daos import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import cy.agorise.bitsybitshareswallet.entities.Balance +import cy.agorise.bitsybitshareswallet.database.entities.Balance @Dao interface BalanceDao { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/EquivalentValueDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/EquivalentValueDao.kt similarity index 72% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/daos/EquivalentValueDao.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/EquivalentValueDao.kt index bb4622e..314c18a 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/EquivalentValueDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/EquivalentValueDao.kt @@ -1,10 +1,10 @@ -package cy.agorise.bitsybitshareswallet.daos +package cy.agorise.bitsybitshareswallet.database.daos import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.Query -import cy.agorise.bitsybitshareswallet.entities.EquivalentValue +import cy.agorise.bitsybitshareswallet.database.entities.EquivalentValue @Dao interface EquivalentValueDao { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/TransferDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/TransferDao.kt similarity index 84% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/daos/TransferDao.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/TransferDao.kt index 48b1092..f61a9e5 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/TransferDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/TransferDao.kt @@ -1,11 +1,11 @@ -package cy.agorise.bitsybitshareswallet.daos +package cy.agorise.bitsybitshareswallet.database.daos import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import cy.agorise.bitsybitshareswallet.entities.Transfer +import cy.agorise.bitsybitshareswallet.database.entities.Transfer import io.reactivex.Single @Dao diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/UserAccountDao.kt similarity index 77% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/UserAccountDao.kt index 3c5d146..9d77877 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/daos/UserAccountDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/UserAccountDao.kt @@ -1,10 +1,10 @@ -package cy.agorise.bitsybitshareswallet.daos +package cy.agorise.bitsybitshareswallet.database.daos import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Insert import androidx.room.Query -import cy.agorise.bitsybitshareswallet.entities.UserAccount +import cy.agorise.bitsybitshareswallet.database.entities.UserAccount @Dao interface UserAccountDao { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Asset.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Asset.kt similarity index 88% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Asset.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Asset.kt index 874968e..80af4de 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Asset.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Asset.kt @@ -1,4 +1,4 @@ -package cy.agorise.bitsybitshareswallet.entities +package cy.agorise.bitsybitshareswallet.database.entities import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Authority.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Authority.kt similarity index 90% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Authority.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Authority.kt index 7ea9c74..50d22c2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Authority.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Authority.kt @@ -1,4 +1,4 @@ -package cy.agorise.bitsybitshareswallet.entities +package cy.agorise.bitsybitshareswallet.database.entities import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Balance.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Balance.kt similarity index 86% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Balance.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Balance.kt index be42d04..b0ae9ad 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Balance.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Balance.kt @@ -1,4 +1,4 @@ -package cy.agorise.bitsybitshareswallet.entities +package cy.agorise.bitsybitshareswallet.database.entities import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/EquivalentValue.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/EquivalentValue.kt similarity index 92% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/entities/EquivalentValue.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/EquivalentValue.kt index 2ff4bd3..a702950 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/EquivalentValue.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/EquivalentValue.kt @@ -1,4 +1,4 @@ -package cy.agorise.bitsybitshareswallet.entities +package cy.agorise.bitsybitshareswallet.database.entities import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Transfer.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Transfer.kt similarity index 94% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Transfer.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Transfer.kt index 4f3166c..f8caf61 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/Transfer.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Transfer.kt @@ -1,4 +1,4 @@ -package cy.agorise.bitsybitshareswallet.entities +package cy.agorise.bitsybitshareswallet.database.entities import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/UserAccount.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/UserAccount.kt similarity index 84% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/entities/UserAccount.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/UserAccount.kt index 011b4ee..df063d2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/entities/UserAccount.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/UserAccount.kt @@ -1,4 +1,4 @@ -package cy.agorise.bitsybitshareswallet.entities +package cy.agorise.bitsybitshareswallet.database.entities import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index 8da9ba0..0a3a5f7 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -14,9 +14,9 @@ import androidx.recyclerview.widget.LinearLayoutManager import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.adapters.BalancesAdapter import cy.agorise.bitsybitshareswallet.adapters.TransactionsAdapter -import cy.agorise.bitsybitshareswallet.entities.Balance -import cy.agorise.bitsybitshareswallet.entities.Transfer -import cy.agorise.bitsybitshareswallet.entities.UserAccount +import cy.agorise.bitsybitshareswallet.database.entities.Balance +import cy.agorise.bitsybitshareswallet.database.entities.Transfer +import cy.agorise.bitsybitshareswallet.database.entities.UserAccount import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.viewmodels.BalanceViewModel import cy.agorise.bitsybitshareswallet.viewmodels.TransactionViewModel diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt index 11cf6f2..2f1df3d 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt @@ -10,7 +10,7 @@ import android.util.Log import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent -import cy.agorise.bitsybitshareswallet.entities.Transfer +import cy.agorise.bitsybitshareswallet.database.entities.Transfer import cy.agorise.bitsybitshareswallet.models.HistoricalOperationEntry import cy.agorise.bitsybitshareswallet.repositories.AuthorityRepository import cy.agorise.bitsybitshareswallet.repositories.TransferRepository diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AssetRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AssetRepository.kt index 8b7c83b..a3cdc1a 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AssetRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AssetRepository.kt @@ -2,9 +2,9 @@ package cy.agorise.bitsybitshareswallet.repositories import android.app.Application import android.os.AsyncTask -import cy.agorise.bitsybitshareswallet.daos.AssetDao -import cy.agorise.bitsybitshareswallet.daos.BitsyDatabase -import cy.agorise.bitsybitshareswallet.entities.Asset +import cy.agorise.bitsybitshareswallet.database.daos.AssetDao +import cy.agorise.bitsybitshareswallet.database.BitsyDatabase +import cy.agorise.bitsybitshareswallet.database.entities.Asset class AssetRepository internal constructor(application: Application) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AuthorityRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AuthorityRepository.kt index 69f7b45..46ad1f3 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AuthorityRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AuthorityRepository.kt @@ -2,9 +2,9 @@ package cy.agorise.bitsybitshareswallet.repositories import android.content.Context import android.os.AsyncTask -import cy.agorise.bitsybitshareswallet.daos.AuthorityDao -import cy.agorise.bitsybitshareswallet.daos.BitsyDatabase -import cy.agorise.bitsybitshareswallet.entities.Authority +import cy.agorise.bitsybitshareswallet.database.daos.AuthorityDao +import cy.agorise.bitsybitshareswallet.database.BitsyDatabase +import cy.agorise.bitsybitshareswallet.database.entities.Authority import io.reactivex.Single class AuthorityRepository internal constructor(context: Context) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceRepository.kt index 201979c..0f36bac 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceRepository.kt @@ -3,9 +3,9 @@ package cy.agorise.bitsybitshareswallet.repositories import android.content.Context import android.os.AsyncTask import androidx.lifecycle.LiveData -import cy.agorise.bitsybitshareswallet.daos.BalanceDao -import cy.agorise.bitsybitshareswallet.daos.BitsyDatabase -import cy.agorise.bitsybitshareswallet.entities.Balance +import cy.agorise.bitsybitshareswallet.database.daos.BalanceDao +import cy.agorise.bitsybitshareswallet.database.BitsyDatabase +import cy.agorise.bitsybitshareswallet.database.entities.Balance class BalanceRepository internal constructor(context: Context) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt index 361a61e..9c27bd2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferRepository.kt @@ -3,9 +3,9 @@ package cy.agorise.bitsybitshareswallet.repositories import android.content.Context import android.os.AsyncTask import androidx.lifecycle.LiveData -import cy.agorise.bitsybitshareswallet.daos.BitsyDatabase -import cy.agorise.bitsybitshareswallet.daos.TransferDao -import cy.agorise.bitsybitshareswallet.entities.Transfer +import cy.agorise.bitsybitshareswallet.database.BitsyDatabase +import cy.agorise.bitsybitshareswallet.database.daos.TransferDao +import cy.agorise.bitsybitshareswallet.database.entities.Transfer import io.reactivex.Single class TransferRepository internal constructor(context: Context) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/UserAccountRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/UserAccountRepository.kt index 569913e..b1a47b8 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/UserAccountRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/UserAccountRepository.kt @@ -3,9 +3,9 @@ package cy.agorise.bitsybitshareswallet.repositories import android.app.Application import android.os.AsyncTask import androidx.lifecycle.LiveData -import cy.agorise.bitsybitshareswallet.daos.BitsyDatabase -import cy.agorise.bitsybitshareswallet.daos.UserAccountDao -import cy.agorise.bitsybitshareswallet.entities.UserAccount +import cy.agorise.bitsybitshareswallet.database.BitsyDatabase +import cy.agorise.bitsybitshareswallet.database.daos.UserAccountDao +import cy.agorise.bitsybitshareswallet.database.entities.UserAccount class UserAccountRepository internal constructor(application: Application) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt index 5949a78..5c4a0b8 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt @@ -3,7 +3,7 @@ package cy.agorise.bitsybitshareswallet.viewmodels import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData -import cy.agorise.bitsybitshareswallet.entities.Balance +import cy.agorise.bitsybitshareswallet.database.entities.Balance import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt index f489b8e..6590fa2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt @@ -3,7 +3,7 @@ package cy.agorise.bitsybitshareswallet.viewmodels import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData -import cy.agorise.bitsybitshareswallet.entities.Transfer +import cy.agorise.bitsybitshareswallet.database.entities.Transfer import cy.agorise.bitsybitshareswallet.repositories.TransferRepository class TransactionViewModel(application: Application) : AndroidViewModel(application) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/UserAccountViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/UserAccountViewModel.kt index ac764d6..1fdf87e 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/UserAccountViewModel.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/UserAccountViewModel.kt @@ -3,7 +3,7 @@ package cy.agorise.bitsybitshareswallet.viewmodels import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData -import cy.agorise.bitsybitshareswallet.entities.UserAccount +import cy.agorise.bitsybitshareswallet.database.entities.UserAccount import cy.agorise.bitsybitshareswallet.repositories.UserAccountRepository class UserAccountViewModel(application: Application) : AndroidViewModel(application) { From cd2f388894af5c0111e9448420d1b43bfd32e467 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Sun, 2 Dec 2018 20:17:31 -0600 Subject: [PATCH 037/129] Created a new BalancesDetail model and DAO to create a object composed form the balances and assets db tables and used such classes to correctly show the balances in the BalancesFragment. --- .../adapters/BalancesAdapter.kt | 30 ++++++++++--------- .../database/BitsyDatabase.kt | 3 ++ .../database/joins/BalanceDetail.kt | 8 +++++ .../database/joins/BalanceDetailDao.kt | 12 ++++++++ .../fragments/BalancesFragment.kt | 14 ++++----- .../repositories/BalanceDetailRepository.kt | 22 ++++++++++++++ .../viewmodels/BalanceDetailViewModel.kt | 16 ++++++++++ .../viewmodels/BalanceViewModel.kt | 16 ---------- 8 files changed, 84 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/BalanceDetail.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/BalanceDetailDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceDetailRepository.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceDetailViewModel.kt delete mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt index 47a1d57..c1df98f 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesAdapter.kt @@ -8,16 +8,16 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SortedList import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.database.entities.Balance +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail class BalancesAdapter(private val context: Context) : RecyclerView.Adapter() { private val mComparator = - Comparator { a, b -> a.assetId.compareTo(b.assetId) } + Comparator { a, b -> a.symbol.compareTo(b.symbol) } private val mSortedList = - SortedList(Balance::class.java, object : SortedList.Callback() { + SortedList(BalanceDetail::class.java, object : SortedList.Callback() { override fun onInserted(position: Int, count: Int) { notifyItemRangeInserted(position, count) } @@ -34,16 +34,16 @@ class BalancesAdapter(private val context: Context) : notifyItemRangeChanged(position, count) } - override fun compare(a: Balance, b: Balance): Int { + override fun compare(a: BalanceDetail, b: BalanceDetail): Int { return mComparator.compare(a, b) } - override fun areContentsTheSame(oldItem: Balance, newItem: Balance): Boolean { + override fun areContentsTheSame(oldItem: BalanceDetail, newItem: BalanceDetail): Boolean { return oldItem == newItem } - override fun areItemsTheSame(item1: Balance, item2: Balance): Boolean { - return item1.assetId == item2.assetId + override fun areItemsTheSame(item1: BalanceDetail, item2: BalanceDetail): Boolean { + return item1.id == item2.id } }) @@ -62,23 +62,25 @@ class BalancesAdapter(private val context: Context) : override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { val balance = mSortedList.get(position) - val amount = "${balance.assetAmount} ${balance.assetId}" - viewHolder.tvBalance.text = amount + val amount = balance.amount.toDouble() / Math.pow(10.0, balance.precision.toDouble()) + + viewHolder.tvBalance.text = + String.format("%." + Math.min(balance.precision, 8) + "f %s", amount, balance.symbol) } - fun add(balance: Balance) { + fun add(balance: BalanceDetail) { mSortedList.add(balance) } - fun remove(balance: Balance) { + fun remove(balance: BalanceDetail) { mSortedList.remove(balance) } - fun add(balances: List) { + fun add(balances: List) { mSortedList.addAll(balances) } - fun remove(balances: List) { + fun remove(balances: List) { mSortedList.beginBatchedUpdates() for (balance in balances) { mSortedList.remove(balance) @@ -86,7 +88,7 @@ class BalancesAdapter(private val context: Context) : mSortedList.endBatchedUpdates() } - fun replaceAll(balances: List) { + fun replaceAll(balances: List) { mSortedList.beginBatchedUpdates() for (i in mSortedList.size() - 1 downTo 0) { val balance = mSortedList.get(i) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt index fc5205a..63078a8 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt @@ -6,6 +6,8 @@ import androidx.room.Room import androidx.room.RoomDatabase import cy.agorise.bitsybitshareswallet.database.daos.* import cy.agorise.bitsybitshareswallet.database.entities.* +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetailDao @Database(entities = [ Asset::class, @@ -24,6 +26,7 @@ abstract class BitsyDatabase : RoomDatabase() { abstract fun equivalentValueDao(): EquivalentValueDao abstract fun transferDao(): TransferDao abstract fun userAccountDao(): UserAccountDao + abstract fun balanceDetailDao(): BalanceDetailDao companion object { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/BalanceDetail.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/BalanceDetail.kt new file mode 100644 index 0000000..ab9e2f9 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/BalanceDetail.kt @@ -0,0 +1,8 @@ +package cy.agorise.bitsybitshareswallet.database.joins + +data class BalanceDetail( + val id: String, + val amount: Long, + val precision: Int, + val symbol: String +) \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/BalanceDetailDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/BalanceDetailDao.kt new file mode 100644 index 0000000..dd7ec5d --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/BalanceDetailDao.kt @@ -0,0 +1,12 @@ +package cy.agorise.bitsybitshareswallet.database.joins + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Query + +@Dao +interface BalanceDetailDao { + @Query("SELECT assets.id AS id, balances.asset_amount AS amount, assets.precision, assets.symbol " + + "FROM balances INNER JOIN assets on balances.asset_id = assets.id") + fun getAll(): LiveData> +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index 0a3a5f7..08fe51d 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -14,11 +14,11 @@ import androidx.recyclerview.widget.LinearLayoutManager import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.adapters.BalancesAdapter import cy.agorise.bitsybitshareswallet.adapters.TransactionsAdapter -import cy.agorise.bitsybitshareswallet.database.entities.Balance import cy.agorise.bitsybitshareswallet.database.entities.Transfer import cy.agorise.bitsybitshareswallet.database.entities.UserAccount +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail import cy.agorise.bitsybitshareswallet.utils.Constants -import cy.agorise.bitsybitshareswallet.viewmodels.BalanceViewModel +import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel import cy.agorise.bitsybitshareswallet.viewmodels.TransactionViewModel import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel import kotlinx.android.synthetic.main.fragment_balances.* @@ -26,7 +26,7 @@ import kotlinx.android.synthetic.main.fragment_balances.* class BalancesFragment : Fragment() { private lateinit var mUserAccountViewModel: UserAccountViewModel - private lateinit var mBalanceViewModel: BalanceViewModel + private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel private lateinit var mTransactionViewModel: TransactionViewModel override fun onCreateView( @@ -49,15 +49,15 @@ class BalancesFragment : Fragment() { tvAccountName.text = user.name }) - // Configure BalanceViewModel to show the current balances - mBalanceViewModel = ViewModelProviders.of(this).get(BalanceViewModel::class.java) + // Configure BalanceDetailViewModel to show the current balances + mBalanceDetailViewModel = ViewModelProviders.of(this).get(BalanceDetailViewModel::class.java) val balancesAdapter = BalancesAdapter(context!!) rvBalances.adapter = balancesAdapter rvBalances.layoutManager = GridLayoutManager(context, 2) - mBalanceViewModel.getAll().observe(this, Observer> { balances -> - balancesAdapter.replaceAll(balances) + mBalanceDetailViewModel.getAll().observe(this, Observer> { balancesDetails -> + balancesAdapter.replaceAll(balancesDetails) }) // Configure TransactionViewModel to show the transaction history diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceDetailRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceDetailRepository.kt new file mode 100644 index 0000000..28c8772 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceDetailRepository.kt @@ -0,0 +1,22 @@ +package cy.agorise.bitsybitshareswallet.repositories + +import android.content.Context +import androidx.lifecycle.LiveData +import cy.agorise.bitsybitshareswallet.database.BitsyDatabase +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetailDao + +class BalanceDetailRepository internal constructor(context: Context) { + + private val mBalanceDetailDao: BalanceDetailDao + + init { + val db = BitsyDatabase.getDatabase(context) + mBalanceDetailDao = db!!.balanceDetailDao() + } + + fun getAll(): LiveData> { + return mBalanceDetailDao.getAll() + } + +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceDetailViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceDetailViewModel.kt new file mode 100644 index 0000000..93fcdfe --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceDetailViewModel.kt @@ -0,0 +1,16 @@ +package cy.agorise.bitsybitshareswallet.viewmodels + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail +import cy.agorise.bitsybitshareswallet.repositories.BalanceDetailRepository + + +class BalanceDetailViewModel(application: Application) : AndroidViewModel(application) { + private var mRepository = BalanceDetailRepository(application) + + internal fun getAll(): LiveData> { + return mRepository.getAll() + } +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt deleted file mode 100644 index 5c4a0b8..0000000 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/BalanceViewModel.kt +++ /dev/null @@ -1,16 +0,0 @@ -package cy.agorise.bitsybitshareswallet.viewmodels - -import android.app.Application -import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.LiveData -import cy.agorise.bitsybitshareswallet.database.entities.Balance -import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository - - -class BalanceViewModel(application: Application) : AndroidViewModel(application) { - private var mRepository = BalanceRepository(application) - - internal fun getAll(): LiveData> { - return mRepository.getAll() - } -} \ No newline at end of file From de75c12197b493d5b030ae473c6936260b394a6e Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Mon, 3 Dec 2018 13:34:13 -0600 Subject: [PATCH 038/129] Created a new TransferDetail model and DAO to create a object composed form the transfers, assets, accounts, and equivalent_values db tables and used such classes to correctly show the accounts involved in transactions in the BalancesFragment. --- ...sactionsAdapter.kt => TransfersAdapter.kt} | 52 +++++++++---------- .../database/BitsyDatabase.kt | 3 +- .../database/joins/TransferDetail.kt | 14 +++++ .../database/joins/TransferDetailDao.kt | 12 +++++ .../fragments/BalancesFragment.kt | 20 +++---- .../repositories/TransferDetailRepository.kt | 22 ++++++++ .../viewmodels/TransactionViewModel.kt | 15 ------ .../viewmodels/TransferDetailViewModel.kt | 15 ++++++ 8 files changed, 101 insertions(+), 52 deletions(-) rename app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/{TransactionsAdapter.kt => TransfersAdapter.kt} (65%) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetail.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetailDao.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferDetailRepository.kt delete mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransferDetailViewModel.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersAdapter.kt similarity index 65% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersAdapter.kt index cf9d490..422a980 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransactionsAdapter.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersAdapter.kt @@ -11,16 +11,16 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SortedList import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.database.entities.Transfer +import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail -class TransactionsAdapter(private val context: Context) : - RecyclerView.Adapter() { +class TransfersAdapter(private val context: Context) : + RecyclerView.Adapter() { private val mComparator = - Comparator { a, b -> a.id.compareTo(b.id) } + Comparator { a, b -> a.id.compareTo(b.id) } private val mSortedList = - SortedList(Transfer::class.java, object : SortedList.Callback() { + SortedList(TransferDetail::class.java, object : SortedList.Callback() { override fun onInserted(position: Int, count: Int) { notifyItemRangeInserted(position, count) } @@ -37,15 +37,15 @@ class TransactionsAdapter(private val context: Context) : notifyItemRangeChanged(position, count) } - override fun compare(a: Transfer, b: Transfer): Int { + override fun compare(a: TransferDetail, b: TransferDetail): Int { return mComparator.compare(a, b) } - override fun areContentsTheSame(oldItem: Transfer, newItem: Transfer): Boolean { + override fun areContentsTheSame(oldItem: TransferDetail, newItem: TransferDetail): Boolean { return oldItem == newItem } - override fun areItemsTheSame(item1: Transfer, item2: Transfer): Boolean { + override fun areItemsTheSame(item1: TransferDetail, item2: TransferDetail): Boolean { return item1.id == item2.id } }) @@ -64,7 +64,7 @@ class TransactionsAdapter(private val context: Context) : val tvFiatEquivalent: TextView = itemView.findViewById(R.id.tvFiatEquivalent) } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionsAdapter.ViewHolder { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransfersAdapter.ViewHolder { val inflater = LayoutInflater.from(context) val transactionView = inflater.inflate(R.layout.item_transaction, parent, false) @@ -73,41 +73,41 @@ class TransactionsAdapter(private val context: Context) : } override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { - val transaction = mSortedList.get(position) + val transferDetail = mSortedList.get(position) - viewHolder.tvFrom.text = transaction.source - viewHolder.tvTo.text = transaction.destination + viewHolder.tvFrom.text = transferDetail.from + viewHolder.tvTo.text = transferDetail.to } - fun add(transaction: Transfer) { - mSortedList.add(transaction) + fun add(transferDetail: TransferDetail) { + mSortedList.add(transferDetail) } - fun remove(transaction: Transfer) { - mSortedList.remove(transaction) + fun remove(transferDetail: TransferDetail) { + mSortedList.remove(transferDetail) } - fun add(transactions: List) { - mSortedList.addAll(transactions) + fun add(transfersDetails: List) { + mSortedList.addAll(transfersDetails) } - fun remove(transactions: List) { + fun remove(transfersDetails: List) { mSortedList.beginBatchedUpdates() - for (transaction in transactions) { - mSortedList.remove(transaction) + for (transferDetail in transfersDetails) { + mSortedList.remove(transferDetail) } mSortedList.endBatchedUpdates() } - fun replaceAll(transactions: List) { + fun replaceAll(transfersDetails: List) { mSortedList.beginBatchedUpdates() for (i in mSortedList.size() - 1 downTo 0) { - val transaction = mSortedList.get(i) - if (!transactions.contains(transaction)) { - mSortedList.remove(transaction) + val transferDetail = mSortedList.get(i) + if (!transfersDetails.contains(transferDetail)) { + mSortedList.remove(transferDetail) } } - mSortedList.addAll(transactions) + mSortedList.addAll(transfersDetails) mSortedList.endBatchedUpdates() } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt index 63078a8..8cfd754 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/BitsyDatabase.kt @@ -6,8 +6,8 @@ import androidx.room.Room import androidx.room.RoomDatabase import cy.agorise.bitsybitshareswallet.database.daos.* import cy.agorise.bitsybitshareswallet.database.entities.* -import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetailDao +import cy.agorise.bitsybitshareswallet.database.joins.TransferDetailDao @Database(entities = [ Asset::class, @@ -27,6 +27,7 @@ abstract class BitsyDatabase : RoomDatabase() { abstract fun transferDao(): TransferDao abstract fun userAccountDao(): UserAccountDao abstract fun balanceDetailDao(): BalanceDetailDao + abstract fun transferDetailDao(): TransferDetailDao companion object { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetail.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetail.kt new file mode 100644 index 0000000..fb46432 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetail.kt @@ -0,0 +1,14 @@ +package cy.agorise.bitsybitshareswallet.database.joins + +data class TransferDetail( + val id: String, + val from: String, + val to: String +// val direction: Boolean, // True -> Received, False -> Sent +// val date: Long, +// val cryptoAmount: Long, +// val cryptoPrecision: Int, +// val cryptoSymbol: String, +// val fiatAmount: Long, +// val fiatCurrency: String +) \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetailDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetailDao.kt new file mode 100644 index 0000000..e027b66 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetailDao.kt @@ -0,0 +1,12 @@ +package cy.agorise.bitsybitshareswallet.database.joins + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Query + +@Dao +interface TransferDetailDao { + + @Query("SELECT id, IFNULL((SELECT name FROM user_accounts WHERE user_accounts.id=transfers.source), '') AS `from`, IFNULL((SELECT name FROM user_accounts WHERE user_accounts.id=transfers.destination), '') AS `to` FROM transfers") + fun getAll(): LiveData> +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index 08fe51d..64a42e3 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -13,13 +13,13 @@ import androidx.recyclerview.widget.LinearLayoutManager import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.adapters.BalancesAdapter -import cy.agorise.bitsybitshareswallet.adapters.TransactionsAdapter -import cy.agorise.bitsybitshareswallet.database.entities.Transfer +import cy.agorise.bitsybitshareswallet.adapters.TransfersAdapter import cy.agorise.bitsybitshareswallet.database.entities.UserAccount import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail +import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel -import cy.agorise.bitsybitshareswallet.viewmodels.TransactionViewModel +import cy.agorise.bitsybitshareswallet.viewmodels.TransferDetailViewModel import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel import kotlinx.android.synthetic.main.fragment_balances.* @@ -27,7 +27,7 @@ class BalancesFragment : Fragment() { private lateinit var mUserAccountViewModel: UserAccountViewModel private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel - private lateinit var mTransactionViewModel: TransactionViewModel + private lateinit var mTransferDetailViewModel: TransferDetailViewModel override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -60,15 +60,15 @@ class BalancesFragment : Fragment() { balancesAdapter.replaceAll(balancesDetails) }) - // Configure TransactionViewModel to show the transaction history - mTransactionViewModel = ViewModelProviders.of(this).get(TransactionViewModel::class.java) + // Configure TransferDetailViewModel to show the transaction history + mTransferDetailViewModel = ViewModelProviders.of(this).get(TransferDetailViewModel::class.java) - val transactionsAdapter = TransactionsAdapter(context!!) - rvTransactions.adapter = transactionsAdapter + val transfersAdapter = TransfersAdapter(context!!) + rvTransactions.adapter = transfersAdapter rvTransactions.layoutManager = LinearLayoutManager(context) - mTransactionViewModel.getAll().observe(this, Observer> { transfers -> - transactionsAdapter.replaceAll(transfers) + mTransferDetailViewModel.getAll().observe(this, Observer> { transfersDetails -> + transfersAdapter.replaceAll(transfersDetails) }) } } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferDetailRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferDetailRepository.kt new file mode 100644 index 0000000..915289d --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferDetailRepository.kt @@ -0,0 +1,22 @@ +package cy.agorise.bitsybitshareswallet.repositories + +import android.content.Context +import androidx.lifecycle.LiveData +import cy.agorise.bitsybitshareswallet.database.BitsyDatabase +import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail +import cy.agorise.bitsybitshareswallet.database.joins.TransferDetailDao + +class TransferDetailRepository internal constructor(context: Context) { + + private val mTransferDetailDao: TransferDetailDao + + init { + val db = BitsyDatabase.getDatabase(context) + mTransferDetailDao = db!!.transferDetailDao() + } + + fun getAll(): LiveData> { + return mTransferDetailDao.getAll() + } + +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt deleted file mode 100644 index 6590fa2..0000000 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransactionViewModel.kt +++ /dev/null @@ -1,15 +0,0 @@ -package cy.agorise.bitsybitshareswallet.viewmodels - -import android.app.Application -import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.LiveData -import cy.agorise.bitsybitshareswallet.database.entities.Transfer -import cy.agorise.bitsybitshareswallet.repositories.TransferRepository - -class TransactionViewModel(application: Application) : AndroidViewModel(application) { - private var mRepository = TransferRepository(application) - - internal fun getAll(): LiveData> { - return mRepository.getAll() - } -} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransferDetailViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransferDetailViewModel.kt new file mode 100644 index 0000000..4521f4d --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransferDetailViewModel.kt @@ -0,0 +1,15 @@ +package cy.agorise.bitsybitshareswallet.viewmodels + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail +import cy.agorise.bitsybitshareswallet.repositories.TransferDetailRepository + +class TransferDetailViewModel(application: Application) : AndroidViewModel(application) { + private var mRepository = TransferDetailRepository(application) + + internal fun getAll(): LiveData> { + return mRepository.getAll() + } +} \ No newline at end of file From 70ebea75b0963a64d415523c7851edbbe85846f0 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Mon, 3 Dec 2018 13:51:36 -0600 Subject: [PATCH 039/129] Add direction to TransferDetail and use it to display the correct left bar color and direction arrow in the Transactions list.. --- .../adapters/TransfersAdapter.kt | 13 +++++++++++++ .../database/joins/TransferDetail.kt | 4 ++-- .../database/joins/TransferDetailDao.kt | 4 ++-- .../fragments/BalancesFragment.kt | 2 +- .../repositories/TransferDetailRepository.kt | 4 ++-- .../viewmodels/TransferDetailViewModel.kt | 4 ++-- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersAdapter.kt index 422a980..631e1bc 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersAdapter.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/TransfersAdapter.kt @@ -1,6 +1,7 @@ package cy.agorise.bitsybitshareswallet.adapters import android.content.Context +import android.preference.PreferenceManager import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -12,10 +13,14 @@ import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SortedList import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail +import cy.agorise.bitsybitshareswallet.utils.Constants class TransfersAdapter(private val context: Context) : RecyclerView.Adapter() { + val userId = PreferenceManager.getDefaultSharedPreferences(context) + .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "")!! + private val mComparator = Comparator { a, b -> a.id.compareTo(b.id) } @@ -75,8 +80,16 @@ class TransfersAdapter(private val context: Context) : override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { val transferDetail = mSortedList.get(position) + viewHolder.vPaymentDirection.setBackgroundColor(context.resources.getColor( + if(transferDetail.direction) R.color.colorReceive else R.color.colorSend + )) + viewHolder.tvFrom.text = transferDetail.from viewHolder.tvTo.text = transferDetail.to + + viewHolder.ivDirectionArrow.setImageDrawable(context.getDrawable( + if(transferDetail.direction) R.drawable.ic_arrow_receive else R.drawable.ic_arrow_send + )) } fun add(transferDetail: TransferDetail) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetail.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetail.kt index fb46432..a490111 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetail.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetail.kt @@ -3,8 +3,8 @@ package cy.agorise.bitsybitshareswallet.database.joins data class TransferDetail( val id: String, val from: String, - val to: String -// val direction: Boolean, // True -> Received, False -> Sent + val to: String, + val direction: Boolean // True -> Received, False -> Sent // val date: Long, // val cryptoAmount: Long, // val cryptoPrecision: Int, diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetailDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetailDao.kt index e027b66..7322a19 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetailDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/joins/TransferDetailDao.kt @@ -7,6 +7,6 @@ import androidx.room.Query @Dao interface TransferDetailDao { - @Query("SELECT id, IFNULL((SELECT name FROM user_accounts WHERE user_accounts.id=transfers.source), '') AS `from`, IFNULL((SELECT name FROM user_accounts WHERE user_accounts.id=transfers.destination), '') AS `to` FROM transfers") - fun getAll(): LiveData> + @Query("SELECT id, IFNULL((SELECT name FROM user_accounts WHERE user_accounts.id=transfers.source), '') AS `from`, IFNULL((SELECT name FROM user_accounts WHERE user_accounts.id=transfers.destination), '') AS `to`, (CASE WHEN destination=:userId THEN 1 ELSE 0 END) AS `direction` FROM transfers") + fun getAll(userId: String): LiveData> } \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index 64a42e3..ef1687a 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -67,7 +67,7 @@ class BalancesFragment : Fragment() { rvTransactions.adapter = transfersAdapter rvTransactions.layoutManager = LinearLayoutManager(context) - mTransferDetailViewModel.getAll().observe(this, Observer> { transfersDetails -> + mTransferDetailViewModel.getAll(userId).observe(this, Observer> { transfersDetails -> transfersAdapter.replaceAll(transfersDetails) }) } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferDetailRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferDetailRepository.kt index 915289d..cd86011 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferDetailRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/TransferDetailRepository.kt @@ -15,8 +15,8 @@ class TransferDetailRepository internal constructor(context: Context) { mTransferDetailDao = db!!.transferDetailDao() } - fun getAll(): LiveData> { - return mTransferDetailDao.getAll() + fun getAll(userId: String): LiveData> { + return mTransferDetailDao.getAll(userId) } } \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransferDetailViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransferDetailViewModel.kt index 4521f4d..39ff1b6 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransferDetailViewModel.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/TransferDetailViewModel.kt @@ -9,7 +9,7 @@ import cy.agorise.bitsybitshareswallet.repositories.TransferDetailRepository class TransferDetailViewModel(application: Application) : AndroidViewModel(application) { private var mRepository = TransferDetailRepository(application) - internal fun getAll(): LiveData> { - return mRepository.getAll() + internal fun getAll(userId: String): LiveData> { + return mRepository.getAll(userId) } } \ No newline at end of file From 75bd1b2e033ec3bbbcb9977f1fce56d1f0fb3780 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Mon, 3 Dec 2018 15:37:27 -0600 Subject: [PATCH 040/129] Created basic SendTransactionFragment and SendTransactionFragment with their respective layout files. --- app/src/main/AndroidManifest.xml | 2 -- .../activities/MainActivity.kt | 21 ++++++++----------- .../activities/ReceiveTransactionActivity.kt | 13 ------------ .../activities/SendTransactionActivity.kt | 13 ------------ .../fragments/ReceiveTransactionFragment.kt | 19 +++++++++++++++++ .../fragments/SendTransactionFragment.kt | 19 +++++++++++++++++ ...n.xml => fragment_receive_transaction.xml} | 7 ++++++- ...tion.xml => fragment_send_transaction.xml} | 7 ++++++- 8 files changed, 59 insertions(+), 42 deletions(-) delete mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ReceiveTransactionActivity.kt delete mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SendTransactionActivity.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ReceiveTransactionFragment.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt rename app/src/main/res/layout/{activity_send_transaction.xml => fragment_receive_transaction.xml} (65%) rename app/src/main/res/layout/{activity_receive_transaction.xml => fragment_send_transaction.xml} (65%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 97989d1..572ce2d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -28,8 +28,6 @@ - - \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 7ba4517..684d8c2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -8,11 +8,14 @@ import android.view.Menu import android.view.MenuItem import android.widget.Toast import androidx.collection.LongSparseArray +import androidx.fragment.app.Fragment import com.google.android.material.bottomnavigation.BottomNavigationView import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.database.entities.Balance import cy.agorise.bitsybitshareswallet.fragments.BalancesFragment import cy.agorise.bitsybitshareswallet.fragments.MerchantsFragment +import cy.agorise.bitsybitshareswallet.fragments.ReceiveTransactionFragment +import cy.agorise.bitsybitshareswallet.fragments.SendTransactionFragment import cy.agorise.bitsybitshareswallet.processors.TransfersLoader import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository import cy.agorise.bitsybitshareswallet.utils.Constants @@ -39,19 +42,19 @@ class MainActivity : ConnectedActivity() { private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> when (item.itemId) { R.id.navigation_receive -> { - Toast.makeText(this, "Receive Fragment", Toast.LENGTH_SHORT).show() + loadFragment(ReceiveTransactionFragment()) return@OnNavigationItemSelectedListener true } R.id.navigation_balances -> { - loadBalancesFragment() + loadFragment(BalancesFragment()) return@OnNavigationItemSelectedListener true } R.id.navigation_merchants -> { - loadMerchantsFragment() + loadFragment(MerchantsFragment()) return@OnNavigationItemSelectedListener true } R.id.navigation_send -> { - Toast.makeText(this, "Send Fragment", Toast.LENGTH_SHORT).show() + loadFragment(SendTransactionFragment()) return@OnNavigationItemSelectedListener true } } @@ -73,15 +76,9 @@ class MainActivity : ConnectedActivity() { mBalanceRepository = BalanceRepository(this) } - private fun loadBalancesFragment() { + private fun loadFragment(fragment: Fragment) { val ft = supportFragmentManager.beginTransaction() - ft.replace(R.id.fragment_frame, BalancesFragment()) - ft.commit() - } - - private fun loadMerchantsFragment() { - val ft = supportFragmentManager.beginTransaction() - ft.replace(R.id.fragment_frame, MerchantsFragment()) + ft.replace(R.id.fragment_frame, fragment) ft.commit() } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ReceiveTransactionActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ReceiveTransactionActivity.kt deleted file mode 100644 index 841493c..0000000 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ReceiveTransactionActivity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package cy.agorise.bitsybitshareswallet.activities - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle -import cy.agorise.bitsybitshareswallet.R - -class ReceiveTransactionActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_receive_transaction) - } -} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SendTransactionActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SendTransactionActivity.kt deleted file mode 100644 index a6969d6..0000000 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SendTransactionActivity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package cy.agorise.bitsybitshareswallet.activities - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle -import cy.agorise.bitsybitshareswallet.R - -class SendTransactionActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_send_transaction) - } -} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ReceiveTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ReceiveTransactionFragment.kt new file mode 100644 index 0000000..d981593 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ReceiveTransactionFragment.kt @@ -0,0 +1,19 @@ +package cy.agorise.bitsybitshareswallet.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import cy.agorise.bitsybitshareswallet.R + +class ReceiveTransactionFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_receive_transaction, container, false) + } + +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt new file mode 100644 index 0000000..a3f3b2a --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt @@ -0,0 +1,19 @@ +package cy.agorise.bitsybitshareswallet.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import cy.agorise.bitsybitshareswallet.R + +class SendTransactionFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_send_transaction, container, false) + } + +} diff --git a/app/src/main/res/layout/activity_send_transaction.xml b/app/src/main/res/layout/fragment_receive_transaction.xml similarity index 65% rename from app/src/main/res/layout/activity_send_transaction.xml rename to app/src/main/res/layout/fragment_receive_transaction.xml index 5500336..91f8797 100644 --- a/app/src/main/res/layout/activity_send_transaction.xml +++ b/app/src/main/res/layout/fragment_receive_transaction.xml @@ -5,6 +5,11 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".activities.SendTransactionActivity"> + tools:context=".fragments.ReceiveTransactionFragment"> + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_receive_transaction.xml b/app/src/main/res/layout/fragment_send_transaction.xml similarity index 65% rename from app/src/main/res/layout/activity_receive_transaction.xml rename to app/src/main/res/layout/fragment_send_transaction.xml index d1b31e3..3a186ed 100644 --- a/app/src/main/res/layout/activity_receive_transaction.xml +++ b/app/src/main/res/layout/fragment_send_transaction.xml @@ -5,6 +5,11 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".activities.ReceiveTransactionActivity"> + tools:context=".fragments.SendTransactionFragment"> + + \ No newline at end of file From 95404708a986b4a793db9728d768db7f781a70e7 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Mon, 3 Dec 2018 17:22:21 -0600 Subject: [PATCH 041/129] Create SendTransactionFragment layout similar to Crystal's --- .../main/res/drawable/ic_arrow_forward.xml | 5 + .../main/res/drawable/send_fab_background.xml | 7 + .../res/layout/fragment_send_transaction.xml | 180 +++++++++++++++++- app/src/main/res/values/colors.xml | 1 + 4 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 app/src/main/res/drawable/ic_arrow_forward.xml create mode 100644 app/src/main/res/drawable/send_fab_background.xml diff --git a/app/src/main/res/drawable/ic_arrow_forward.xml b/app/src/main/res/drawable/ic_arrow_forward.xml new file mode 100644 index 0000000..25fb386 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_forward.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/send_fab_background.xml b/app/src/main/res/drawable/send_fab_background.xml new file mode 100644 index 0000000..6b31518 --- /dev/null +++ b/app/src/main/res/drawable/send_fab_background.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_send_transaction.xml b/app/src/main/res/layout/fragment_send_transaction.xml index 3a186ed..4b5c111 100644 --- a/app/src/main/res/layout/fragment_send_transaction.xml +++ b/app/src/main/res/layout/fragment_send_transaction.xml @@ -1,15 +1,181 @@ - + android:layout_height="match_parent"> - + android:layout_height="wrap_content" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + tools:context=".fragments.SendTransactionFragment"> - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 411afcc..cce4962 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,6 +7,7 @@ #000 #888 #e0e0e0 + #616161 #669900 #DC473A From fa2c7a07d816e1f7690ad6a1a7259c34ccdd095a Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Tue, 4 Dec 2018 11:33:58 -0600 Subject: [PATCH 042/129] Add camera permission to Manifest to be able to use camera in the app to read QR codes. - Add methods to SendTransactionFragment to request camera permission and start/stop the camera preview accordingly. --- app/src/main/AndroidManifest.xml | 2 + .../fragments/SendTransactionFragment.kt | 90 +++++++++++++++++-- app/src/main/res/drawable/ic_close.xml | 5 ++ .../res/layout/fragment_send_transaction.xml | 5 +- 4 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 app/src/main/res/drawable/ic_close.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 572ce2d..ca59e1b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="cy.agorise.bitsybitshareswallet"> + + , grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + + if (requestCode == REQUEST_CAMERA_PERMISSION) { + if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { + startCameraPreview() + } else { + // TODO extract string resource + Toast.makeText(context!!, "Camera permission is necessary to read QR codes.", Toast.LENGTH_SHORT).show() + } + return + } + } + + private fun startCameraPreview() { + cameraPreview.visibility = View.VISIBLE + fabOpenCamera.setImageResource(R.drawable.ic_close) + isCameraPreviewVisible = true + + // Configure QR scanner + cameraPreview.setFormats(listOf(BarcodeFormat.QR_CODE)) + cameraPreview.setAspectTolerance(0.5f) + cameraPreview.setAutoFocus(true) + cameraPreview.setLaserColor(R.color.colorAccent) + cameraPreview.setMaskColor(R.color.colorAccent) + cameraPreview.setResultHandler(this) + cameraPreview.startCamera() + } + + private fun stopCameraPreview() { + cameraPreview.visibility = View.INVISIBLE + fabOpenCamera.setImageResource(R.drawable.ic_camera) + isCameraPreviewVisible = false + cameraPreview.stopCamera() + } + + override fun handleResult(result: Result?) { + Toast.makeText(context!!, result!!.text, Toast.LENGTH_SHORT).show() + } + + override fun onResume() { + super.onResume() + if (isCameraPreviewVisible) + startCameraPreview() + } + + override fun onPause() { + super.onPause() + if (!isCameraPreviewVisible) + stopCameraPreview() + } } diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml new file mode 100644 index 0000000..0c8775c --- /dev/null +++ b/app/src/main/res/drawable/ic_close.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_send_transaction.xml b/app/src/main/res/layout/fragment_send_transaction.xml index 4b5c111..74fe56b 100644 --- a/app/src/main/res/layout/fragment_send_transaction.xml +++ b/app/src/main/res/layout/fragment_send_transaction.xml @@ -42,6 +42,7 @@ android:id="@+id/tietTo" android:layout_width="match_parent" android:layout_height="wrap_content" + android:digits="abcdefghijklmnopqrstuvwxyz-0123456789" android:maxLines="1"/> @@ -135,7 +136,7 @@ app:layout_constraintEnd_toStartOf="@id/cameraVerticalGuideline"/> Date: Tue, 4 Dec 2018 15:49:22 -0600 Subject: [PATCH 043/129] - Create AssetsAdapter to populate the Assets Spinner in SendTransactionFragment. - Use BalanceDetailViewModel to fetch the Balance details from the database and pass them to the AssetsAdapter. --- .../adapters/AssetsAdapter.kt | 42 ++++++++++++++ .../fragments/SendTransactionFragment.kt | 57 ++++++++++++++++++- .../repositories/BalanceDetailRepository.kt | 1 - .../main/res/drawable/send_fab_background.xml | 4 +- .../res/layout/fragment_send_transaction.xml | 8 +-- 5 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/AssetsAdapter.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/AssetsAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/AssetsAdapter.kt new file mode 100644 index 0000000..3911159 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/AssetsAdapter.kt @@ -0,0 +1,42 @@ +package cy.agorise.bitsybitshareswallet.adapters + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.TextView +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail + + + +class AssetsAdapter(context: Context, resource: Int, data: List) : + ArrayAdapter(context, resource, data) { + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + var cv = convertView + + if (cv == null) { + val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + cv = inflater.inflate(android.R.layout.simple_spinner_item, parent, false) + } + + val text: TextView = cv!!.findViewById(android.R.id.text1) + + val balanceDetail = getItem(position) + text.text = balanceDetail!!.symbol + + return cv + } + + override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View { + val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + val v = inflater.inflate(android.R.layout.simple_spinner_dropdown_item, parent, false) + val text: TextView = v.findViewById(android.R.id.text1) + + val balanceDetail = getItem(position) + text.text = balanceDetail!!.symbol + + return v + } +} \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt index 57578c5..c424c47 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt @@ -3,25 +3,44 @@ package cy.agorise.bitsybitshareswallet.fragments import android.Manifest import android.content.pm.PackageManager import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProviders import com.google.zxing.BarcodeFormat import com.google.zxing.Result import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.adapters.AssetsAdapter +import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail +import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel +import cy.agorise.graphenej.Invoice import kotlinx.android.synthetic.main.fragment_send_transaction.* import me.dm7.barcodescanner.zxing.ZXingScannerView +import java.math.RoundingMode +import java.text.DecimalFormat +import java.text.DecimalFormatSymbols +import java.util.Locale class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { + private val TAG = this.javaClass.simpleName // Camera Permission private val REQUEST_CAMERA_PERMISSION = 1 private var isCameraPreviewVisible = false + private var mBalancesDetails: List? = null + + private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel + + private var mAssetsAdapter: AssetsAdapter? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_send_transaction, container, false) } @@ -32,6 +51,15 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { verifyCameraPermission() fabOpenCamera.setOnClickListener { if (isCameraPreviewVisible) stopCameraPreview() else verifyCameraPermission() } + + // Configure BalanceDetailViewModel to show the current balances + mBalanceDetailViewModel = ViewModelProviders.of(this).get(BalanceDetailViewModel::class.java) + + mBalanceDetailViewModel.getAll().observe(this, Observer> { balancesDetails -> + mBalancesDetails = balancesDetails + mAssetsAdapter = AssetsAdapter(context!!, android.R.layout.simple_spinner_item, mBalancesDetails!!) + spAsset.adapter = mAssetsAdapter + }) } private fun verifyCameraPermission() { @@ -82,7 +110,34 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { } override fun handleResult(result: Result?) { - Toast.makeText(context!!, result!!.text, Toast.LENGTH_SHORT).show() + try { + val invoice = Invoice.fromQrCode(result!!.text) + + Log.d(TAG, "QR Code read: " + invoice.toJsonString()) + + tietTo.setText(invoice.to) + + for (i in 0 until mAssetsAdapter!!.count) { + if (mAssetsAdapter!!.getItem(i)!!.symbol == invoice.currency.toUpperCase()) { + spAsset.setSelection(i) + break + } + } + tietMemo.setText(invoice.memo) + + + var amount = 0.0 + for (nextItem in invoice.lineItems) { + amount += nextItem.quantity * nextItem.price + } + val df = DecimalFormat("####.#####") + df.roundingMode = RoundingMode.CEILING + df.decimalFormatSymbols = DecimalFormatSymbols(Locale.getDefault()) + tietAmount.setText(df.format(amount)) + + }catch (e: Exception) { + Log.d(TAG, "Invoice error: " + e.message) + } } override fun onResume() { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceDetailRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceDetailRepository.kt index 28c8772..edecb7d 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceDetailRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/BalanceDetailRepository.kt @@ -18,5 +18,4 @@ class BalanceDetailRepository internal constructor(context: Context) { fun getAll(): LiveData> { return mBalanceDetailDao.getAll() } - } \ No newline at end of file diff --git a/app/src/main/res/drawable/send_fab_background.xml b/app/src/main/res/drawable/send_fab_background.xml index 6b31518..a8c2324 100644 --- a/app/src/main/res/drawable/send_fab_background.xml +++ b/app/src/main/res/drawable/send_fab_background.xml @@ -1,7 +1,7 @@ + android:bottomLeftRadius="60dp" + android:topLeftRadius="60dp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_send_transaction.xml b/app/src/main/res/layout/fragment_send_transaction.xml index 74fe56b..a665e66 100644 --- a/app/src/main/res/layout/fragment_send_transaction.xml +++ b/app/src/main/res/layout/fragment_send_transaction.xml @@ -157,8 +157,8 @@ Date: Wed, 5 Dec 2018 10:10:45 -0600 Subject: [PATCH 044/129] Add methods to remember the currently selected Spinner's Asset and make sure that selection is not lost when the balances table is updated. Make an improvement to the camera feed UI. --- .../fragments/SendTransactionFragment.kt | 25 +++++++++++++++++++ .../res/drawable/camera_view_background.xml | 5 ++++ .../res/layout/fragment_send_transaction.xml | 5 ++-- 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/drawable/camera_view_background.xml diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt index c424c47..edf0056 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt @@ -7,6 +7,7 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.AdapterView import android.widget.Toast import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment @@ -40,6 +41,8 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { private var mAssetsAdapter: AssetsAdapter? = null + private var selectedAssetSymbol = "" + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_send_transaction, container, false) @@ -59,7 +62,25 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { mBalancesDetails = balancesDetails mAssetsAdapter = AssetsAdapter(context!!, android.R.layout.simple_spinner_item, mBalancesDetails!!) spAsset.adapter = mAssetsAdapter + + // Try to select the selectedAssetSymbol + for (i in 0 until mAssetsAdapter!!.count) { + if (mAssetsAdapter!!.getItem(i)!!.symbol == selectedAssetSymbol) { + spAsset.setSelection(i) + break + } + } }) + + spAsset.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{ + override fun onNothingSelected(parent: AdapterView<*>?) { } + + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + selectedAssetSymbol = mAssetsAdapter!!.getItem(position)!!.symbol + } + } + + fabSendTransaction.setOnClickListener { validateFields() } } private fun verifyCameraPermission() { @@ -140,6 +161,10 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { } } + private fun validateFields() { + + } + override fun onResume() { super.onResume() if (isCameraPreviewVisible) diff --git a/app/src/main/res/drawable/camera_view_background.xml b/app/src/main/res/drawable/camera_view_background.xml new file mode 100644 index 0000000..3557241 --- /dev/null +++ b/app/src/main/res/drawable/camera_view_background.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_send_transaction.xml b/app/src/main/res/layout/fragment_send_transaction.xml index a665e66..0e06f22 100644 --- a/app/src/main/res/layout/fragment_send_transaction.xml +++ b/app/src/main/res/layout/fragment_send_transaction.xml @@ -123,12 +123,11 @@ Date: Wed, 5 Dec 2018 18:38:34 -0600 Subject: [PATCH 045/129] - Added the RxBindings library to be able to use RxJava on Android Widgets. - Connected the SendTransactionFragment to Graphenej's NetworkService so that it can directly send requests to the nodes. - Added the RxBus to SendTransactionsFragment so that it can listen to responses from the NetworkService and take the useful ones. - Added account validation to SendTransactionFragment, if the account typed exists then the Send button is enabled, if not the button is disabled an a error is shown below the typed account. --- app/build.gradle | 1 + .../activities/MainActivity.kt | 1 - .../fragments/SendTransactionFragment.kt | 119 +++++++++++++++++- 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a45fff0..48248b1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,6 +47,7 @@ dependencies { kapt "androidx.room:room-compiler:$room_version" implementation "androidx.room:room-rxjava2:$room_version" // RxJava support for Room + implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' implementation 'org.bitcoinj:bitcoinj-core:0.14.3' implementation 'com.moldedbits.r2d2:r2d2:1.0.1' diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 684d8c2..688e972 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -6,7 +6,6 @@ import android.preference.PreferenceManager import android.util.Log import android.view.Menu import android.view.MenuItem -import android.widget.Toast import androidx.collection.LongSparseArray import androidx.fragment.app.Fragment import com.google.android.material.bottomnavigation.BottomNavigationView diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt index edf0056..14dd5ee 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt @@ -1,8 +1,14 @@ package cy.agorise.bitsybitshareswallet.fragments import android.Manifest +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.content.pm.PackageManager import android.os.Bundle +import android.os.IBinder +import android.preference.PreferenceManager import android.util.Log import android.view.LayoutInflater import android.view.View @@ -15,24 +21,39 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.google.zxing.BarcodeFormat import com.google.zxing.Result +import com.jakewharton.rxbinding2.widget.RxTextView import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.adapters.AssetsAdapter import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail +import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel import cy.agorise.graphenej.Invoice +import cy.agorise.graphenej.UserAccount +import cy.agorise.graphenej.api.ConnectionStatusUpdate +import cy.agorise.graphenej.api.android.NetworkService +import cy.agorise.graphenej.api.android.RxBus +import cy.agorise.graphenej.api.calls.GetAccountByName +import cy.agorise.graphenej.models.AccountProperties +import cy.agorise.graphenej.models.JsonRpcResponse +import cy.agorise.graphenej.operations.TransferOperationBuilder +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable import kotlinx.android.synthetic.main.fragment_send_transaction.* import me.dm7.barcodescanner.zxing.ZXingScannerView import java.math.RoundingMode import java.text.DecimalFormat import java.text.DecimalFormatSymbols import java.util.Locale +import java.util.concurrent.TimeUnit -class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { +class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, ServiceConnection { private val TAG = this.javaClass.simpleName // Camera Permission private val REQUEST_CAMERA_PERMISSION = 1 + private val RESPONSE_GET_ACCOUNT_BY_NAME = 1 + private var isCameraPreviewVisible = false private var mBalancesDetails: List? = null @@ -43,6 +64,22 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { private var selectedAssetSymbol = "" + /** Current user account */ + private var mUserAccount: UserAccount? = null + + /** User account to which send the funds */ + private var mSelectedUserAccount: UserAccount? = null + + private var mDisposables = CompositeDisposable() + + /* Network service connection */ + private var mNetworkService: NetworkService? = null + + /** Flag used to keep track of the NetworkService binding state */ + private var mShouldUnbindNetwork: Boolean = false + + // Map used to keep track of request and response id pairs + private val responseMap = HashMap() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_send_transaction, container, false) @@ -51,6 +88,12 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + val userId = PreferenceManager.getDefaultSharedPreferences(context) + .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") + + if (userId != "") + mUserAccount = UserAccount(userId) + verifyCameraPermission() fabOpenCamera.setOnClickListener { if (isCameraPreviewVisible) stopCameraPreview() else verifyCameraPermission() } @@ -81,6 +124,52 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { } fabSendTransaction.setOnClickListener { validateFields() } + fabSendTransaction.hide() + + // Use RxJava Debounce to avoid making calls to the NetworkService on every text change event + mDisposables.add(RxTextView.textChanges(tietTo) + .map { it.toString().trim() } + .filter { it.length > 1 } + .debounce(500, TimeUnit.MILLISECONDS) + .subscribe { + val id = mNetworkService!!.sendMessage(GetAccountByName(it!!), GetAccountByName.REQUIRED_API) + responseMap[id] = RESPONSE_GET_ACCOUNT_BY_NAME + } + ) + + mDisposables.add(RxBus.getBusInstance() + .asFlowable() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { message -> + if (message is JsonRpcResponse<*>) { + if (responseMap.containsKey(message.id)) { + val responseType = responseMap[message.id] + when (responseType) { + RESPONSE_GET_ACCOUNT_BY_NAME -> handleAccountName(message.result) + } + responseMap.remove(message.id) + } + } else if (message is ConnectionStatusUpdate) { + if (message.updateCode == ConnectionStatusUpdate.DISCONNECTED) { + // If we got a disconnection notification, we should clear our response map, since + // all its stored request ids will now be reset + responseMap.clear() + } + } + } + ) + } + + private fun handleAccountName(result: Any?) { + if (result is AccountProperties) { + mSelectedUserAccount = UserAccount(result.id, result.name) + tilTo.isErrorEnabled = false + fabSendTransaction.show() + } else { + mSelectedUserAccount = null + tilTo.error = "Invalid account" + fabSendTransaction.hide() + } } private fun verifyCameraPermission() { @@ -162,13 +251,27 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { } private fun validateFields() { + tilAmount.isErrorEnabled = false +// val selectedAsset = mAssetsAdapter!!.getItem(spAsset.selectedItemPosition) +// val selectedAmount = tietAmount.getTex + + // Create TransferOperation + val builder = TransferOperationBuilder() + builder.setSource(mUserAccount) } override fun onResume() { super.onResume() if (isCameraPreviewVisible) startCameraPreview() + + val intent = Intent(context, NetworkService::class.java) + if (context!!.bindService(intent, this, Context.BIND_AUTO_CREATE)) { + mShouldUnbindNetwork = true + } else { + Log.e(TAG, "Binding to the network service failed.") + } } override fun onPause() { @@ -176,4 +279,18 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler { if (!isCameraPreviewVisible) stopCameraPreview() } + + override fun onDestroy() { + super.onDestroy() + + if (!mDisposables.isDisposed) mDisposables.dispose() + } + + override fun onServiceDisconnected(name: ComponentName?) { } + + override fun onServiceConnected(name: ComponentName?, service: IBinder?) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + val binder = service as NetworkService.LocalBinder + mNetworkService = binder.service + } } From 53479f8837f0d56243f7444fd32b9cd37040ba00 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 5 Dec 2018 21:49:26 -0600 Subject: [PATCH 046/129] - Add a amount verification to the SendTransactionFragment to ensure the user has at least that amount of the selected asset in his account. - Show the balance of the current selected asset below the asset Spinner. - Enable the send transaction button only after verifying that both the to account and the amount are both valid. --- .../fragments/SendTransactionFragment.kt | 55 +++++++++++++++---- .../res/layout/fragment_send_transaction.xml | 15 ++++- app/src/main/res/values/styles.xml | 1 + 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt index 14dd5ee..ca823c2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt @@ -55,6 +55,8 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv private val RESPONSE_GET_ACCOUNT_BY_NAME = 1 private var isCameraPreviewVisible = false + private var isToAccountCorrect = false + private var isAmountCorrect = false private var mBalancesDetails: List? = null @@ -119,7 +121,13 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv override fun onNothingSelected(parent: AdapterView<*>?) { } override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - selectedAssetSymbol = mAssetsAdapter!!.getItem(position)!!.symbol + val balance = mAssetsAdapter!!.getItem(position)!! + selectedAssetSymbol = balance.symbol + + val amount = balance.amount.toDouble() / Math.pow(10.0, balance.precision.toDouble()) + + tvAvailableAssetAmount.text = + String.format("%." + Math.min(balance.precision, 8) + "f %s", amount, balance.symbol) } } @@ -128,15 +136,23 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv // Use RxJava Debounce to avoid making calls to the NetworkService on every text change event mDisposables.add(RxTextView.textChanges(tietTo) + .debounce(500, TimeUnit.MILLISECONDS) .map { it.toString().trim() } .filter { it.length > 1 } - .debounce(500, TimeUnit.MILLISECONDS) .subscribe { val id = mNetworkService!!.sendMessage(GetAccountByName(it!!), GetAccountByName.REQUIRED_API) responseMap[id] = RESPONSE_GET_ACCOUNT_BY_NAME } ) + mDisposables.add(RxTextView.textChanges(tietAmount) + .debounce(500, TimeUnit.MILLISECONDS) + .filter { it.isNotEmpty() } + .map { it.toString().trim().toDouble() } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { validateAmount(it!!) } + ) + mDisposables.add(RxBus.getBusInstance() .asFlowable() .observeOn(AndroidSchedulers.mainThread()) @@ -164,12 +180,14 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv if (result is AccountProperties) { mSelectedUserAccount = UserAccount(result.id, result.name) tilTo.isErrorEnabled = false - fabSendTransaction.show() + isToAccountCorrect = true } else { mSelectedUserAccount = null tilTo.error = "Invalid account" - fabSendTransaction.hide() + isToAccountCorrect = false } + + enableDisableSendFAB() } private fun verifyCameraPermission() { @@ -250,13 +268,30 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv } } + private fun validateAmount(amount: Double) { + val balance = mAssetsAdapter!!.getItem(spAsset.selectedItemPosition)!! + val currentAmount = balance.amount.toDouble() / Math.pow(10.0, balance.precision.toDouble()) + + if (currentAmount < amount) { + tilAmount.error = "Not enough funds" + isAmountCorrect = false + } else { + tilAmount.isErrorEnabled = false + isAmountCorrect = true + } + + enableDisableSendFAB() + } + + private fun enableDisableSendFAB() { + if (isToAccountCorrect && isAmountCorrect) + fabSendTransaction.show() + else + fabSendTransaction.hide() + } + private fun validateFields() { - tilAmount.isErrorEnabled = false - -// val selectedAsset = mAssetsAdapter!!.getItem(spAsset.selectedItemPosition) -// val selectedAmount = tietAmount.getTex - - // Create TransferOperation + // Create TransferOperation val builder = TransferOperationBuilder() builder.setSource(mUserAccount) } diff --git a/app/src/main/res/layout/fragment_send_transaction.xml b/app/src/main/res/layout/fragment_send_transaction.xml index 0e06f22..66d8e71 100644 --- a/app/src/main/res/layout/fragment_send_transaction.xml +++ b/app/src/main/res/layout/fragment_send_transaction.xml @@ -43,7 +43,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:digits="abcdefghijklmnopqrstuvwxyz-0123456789" - android:maxLines="1"/> + android:maxLines="1" + android:lines="1" + android:imeOptions="actionNext"/> @@ -90,6 +92,17 @@ app:layout_constraintEnd_toEndOf="@+id/spAsset" app:layout_constraintStart_toStartOf="@+id/spAsset" /> + + - From 82efa60a367de49dcdfbb8e805146fed4a6f5437 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 12 Dec 2018 20:56:20 -0600 Subject: [PATCH 063/129] Introduce the new Android Architecture Components' Navigation. - Remove the old MainActivity layout that included a BottomNavigationView. - Start using the Navigation AAC and make the BalancesFragment the default Fragment so that it is the first to appear. --- app/build.gradle | 5 ++ app/src/main/AndroidManifest.xml | 1 + .../activities/MainActivity.kt | 65 +------------------ app/src/main/res/layout/activity_main.xml | 37 +++++------ .../main/res/navigation/mobile_navigation.xml | 15 +++++ 5 files changed, 39 insertions(+), 84 deletions(-) create mode 100644 app/src/main/res/navigation/mobile_navigation.xml diff --git a/app/build.gradle b/app/build.gradle index 2cc55f6..b01f760 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,6 +33,7 @@ android { dependencies { def lifecycle_version = "2.0.0" def room_version = "2.1.0-alpha03" + def nav_version = "1.0.0-alpha08" implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(':graphenejlib:graphenej') @@ -48,6 +49,10 @@ dependencies { kapt "androidx.room:room-compiler:$room_version" implementation "androidx.room:room-rxjava2:$room_version" // RxJava support for Room + implementation "android.arch.navigation:navigation-fragment-ktx:$nav_version" + implementation "android.arch.navigation:navigation-ui-ktx:$nav_version" + + implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' implementation 'org.bitcoinj:bitcoinj-core:0.14.3' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 74048ff..914a868 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -28,6 +28,7 @@ - when (item.itemId) { - R.id.navigation_receive -> { - loadFragment(ReceiveTransactionFragment()) - return@OnNavigationItemSelectedListener true - } - R.id.navigation_balances -> { - loadFragment(BalancesFragment()) - return@OnNavigationItemSelectedListener true - } - R.id.navigation_merchants -> { - loadFragment(MerchantsFragment()) - return@OnNavigationItemSelectedListener true - } - R.id.navigation_send -> { - loadFragment(SendTransactionFragment()) - return@OnNavigationItemSelectedListener true - } - } - false - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - - navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) - navigation.selectedItemId = R.id.navigation_balances - } - - private fun loadFragment(fragment: Fragment) { - val ft = supportFragmentManager.beginTransaction() - ft.replace(R.id.fragment_frame, fragment) - ft.commit() - } - - override fun onCreateOptionsMenu(menu: Menu?): Boolean { - // Inflates the menu and places it in the toolbar - menuInflater.inflate(R.menu.menu_main, menu) - - return true - } - - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - return if (item!!.itemId == R.id.menu_settings) { - val intent = Intent(this, SettingsActivity::class.java) - startActivity(intent) - true - } else { - super.onOptionsItemSelected(item) - } } override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) { @@ -80,11 +22,6 @@ class MainActivity : ConnectedActivity() { * @param connectionStatusUpdate Connection status update. */ override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) { - when (connectionStatusUpdate.updateCode) { - ConnectionStatusUpdate.CONNECTED -> { /* Do nothing for now */ } - ConnectionStatusUpdate.DISCONNECTED -> { /* Do nothing for now */ } - ConnectionStatusUpdate.AUTHENTICATED -> {}//updateBalances() } - ConnectionStatusUpdate.API_UPDATE -> { } - } + } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c2bbe0d..9411d90 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,30 +1,27 @@ - - + - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml new file mode 100644 index 0000000..c362807 --- /dev/null +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file From 3d6ce645b5ba5cd7a1af1b4547da3067a09dcc30 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 12 Dec 2018 21:30:27 -0600 Subject: [PATCH 064/129] Make proper configurations to enable the Navigation component and make use of it to add the navigation to the Merchants fragment and back to the Balances fragment. --- .../activities/MainActivity.kt | 45 +++++++++++++++++++ .../fragments/BalancesFragment.kt | 10 +++-- app/src/main/res/layout/activity_main.xml | 2 +- app/src/main/res/menu/menu_balances.xml | 17 +++++++ app/src/main/res/menu/navigation.xml | 24 ---------- .../main/res/navigation/mobile_navigation.xml | 5 ++- 6 files changed, 74 insertions(+), 29 deletions(-) create mode 100644 app/src/main/res/menu/menu_balances.xml delete mode 100644 app/src/main/res/menu/navigation.xml diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 3e08d8b..52160f9 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -1,16 +1,61 @@ package cy.agorise.bitsybitshareswallet.activities +import android.content.res.Resources import android.os.Bundle +import android.view.MenuItem +import androidx.navigation.findNavController +import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.navigateUp +import androidx.navigation.ui.onNavDestinationSelected +import androidx.navigation.ui.setupActionBarWithNavController import cy.agorise.bitsybitshareswallet.R import cy.agorise.graphenej.api.ConnectionStatusUpdate import cy.agorise.graphenej.models.JsonRpcResponse +import kotlinx.android.synthetic.main.activity_main.* class MainActivity : ConnectedActivity() { private val TAG = this.javaClass.simpleName + private lateinit var appBarConfiguration : AppBarConfiguration + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + setSupportActionBar(toolbar) + + val host: NavHostFragment = supportFragmentManager + .findFragmentById(R.id.navHostFragment) as NavHostFragment? ?: return + + // Set up Action Bar + val navController = host.navController + + appBarConfiguration = AppBarConfiguration(navController.graph) + + setupActionBarWithNavController(navController, appBarConfiguration) + + navController.addOnDestinationChangedListener { _, destination, _ -> + val dest: String = try { + resources.getResourceName(destination.id) + } catch (e: Resources.NotFoundException) { + Integer.toString(destination.id) + } + } + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + // Have the NavigationUI look for an action or destination matching the menu + // item id and navigate there if found. + // Otherwise, bubble up to the parent. + return item.onNavDestinationSelected(findNavController(R.id.navHostFragment)) + || super.onOptionsItemSelected(item) + } + + override fun onSupportNavigateUp(): Boolean { + // Allows NavigationUI to support proper up navigation or the drawer layout + // drawer menu, depending on the situation + return findNavController(R.id.navHostFragment).navigateUp(appBarConfiguration) } override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index 3d27ddf..290fd58 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -3,10 +3,8 @@ package cy.agorise.bitsybitshareswallet.fragments import androidx.lifecycle.ViewModelProviders import android.os.Bundle import android.preference.PreferenceManager +import android.view.* import androidx.fragment.app.Fragment -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup import androidx.lifecycle.Observer import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager @@ -33,6 +31,8 @@ class BalancesFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { + setHasOptionsMenu(true) + return inflater.inflate(R.layout.fragment_balances, container, false) } @@ -71,4 +71,8 @@ class BalancesFragment : Fragment() { transfersDetailsAdapter.replaceAll(transfersDetails) }) } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_balances, menu) + } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 9411d90..cbd06d5 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -16,7 +16,7 @@ android:theme="@style/ThemeOverlay.AppCompat.Dark" /> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/navigation.xml b/app/src/main/res/menu/navigation.xml deleted file mode 100644 index ddf6911..0000000 --- a/app/src/main/res/menu/navigation.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index c362807..966e57e 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -9,7 +9,10 @@ + \ No newline at end of file From 2619541e166ec60cf282c240121fbbbac8f30f68 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 13 Dec 2018 08:20:17 -0600 Subject: [PATCH 065/129] - Create and add the new Transactions, Merchants and Settings icons and use them in the Balances toolbar. - Remove the transactions section from the Balances fragment. - Create a new TransactionsFragment which hosts the list of trasactions. - Add the transactions destination to the navigation graph so that the Navigation component automatically handles the transition when the transactions icon is selected in Balances. --- .../fragments/BalancesFragment.kt | 12 ----- .../fragments/TransactionsFragment.kt | 53 +++++++++++++++++++ app/src/main/res/drawable/ic_merchants.xml | 17 +++--- app/src/main/res/drawable/ic_settings.xml | 2 +- app/src/main/res/drawable/ic_transactions.xml | 9 ++++ app/src/main/res/layout/fragment_balances.xml | 14 ----- .../main/res/layout/fragment_transactions.xml | 15 ++++++ app/src/main/res/menu/menu_balances.xml | 8 ++- .../main/res/navigation/mobile_navigation.xml | 15 ++++-- 9 files changed, 107 insertions(+), 38 deletions(-) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt create mode 100644 app/src/main/res/drawable/ic_transactions.xml create mode 100644 app/src/main/res/layout/fragment_transactions.xml diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index 290fd58..0bbc505 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -25,7 +25,6 @@ class BalancesFragment : Fragment() { private lateinit var mUserAccountViewModel: UserAccountViewModel private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel - private lateinit var mTransferDetailViewModel: TransferDetailViewModel override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -59,17 +58,6 @@ class BalancesFragment : Fragment() { mBalanceDetailViewModel.getAll().observe(this, Observer> { balancesDetails -> balancesAdapter.replaceAll(balancesDetails) }) - - // Configure TransferDetailViewModel to show the transaction history - mTransferDetailViewModel = ViewModelProviders.of(this).get(TransferDetailViewModel::class.java) - - val transfersDetailsAdapter = TransfersDetailsAdapter(context!!) - rvTransactions.adapter = transfersDetailsAdapter - rvTransactions.layoutManager = LinearLayoutManager(context) - - mTransferDetailViewModel.getAll(userId).observe(this, Observer> { transfersDetails -> - transfersDetailsAdapter.replaceAll(transfersDetails) - }) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt new file mode 100644 index 0000000..bcbe7da --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/TransactionsFragment.kt @@ -0,0 +1,53 @@ +package cy.agorise.bitsybitshareswallet.fragments + +import android.os.Bundle +import android.preference.PreferenceManager +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProviders +import androidx.recyclerview.widget.LinearLayoutManager +import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.adapters.TransfersDetailsAdapter +import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail +import cy.agorise.bitsybitshareswallet.utils.Constants +import cy.agorise.bitsybitshareswallet.viewmodels.TransferDetailViewModel +import kotlinx.android.synthetic.main.fragment_transactions.* + +class TransactionsFragment : Fragment() { + + private lateinit var mTransferDetailViewModel: TransferDetailViewModel + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { +// setHasOptionsMenu(true) + + return inflater.inflate(R.layout.fragment_transactions, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val userId = PreferenceManager.getDefaultSharedPreferences(context) + .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") ?: "" + + // Configure TransferDetailViewModel to show the transaction history + mTransferDetailViewModel = ViewModelProviders.of(this).get(TransferDetailViewModel::class.java) + + val transfersDetailsAdapter = TransfersDetailsAdapter(context!!) + rvTransactions.adapter = transfersDetailsAdapter + rvTransactions.layoutManager = LinearLayoutManager(context) + + mTransferDetailViewModel.getAll(userId).observe(this, Observer> { transfersDetails -> + transfersDetailsAdapter.replaceAll(transfersDetails) + }) + } + +// override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { +// inflater.inflate(R.menu.menu_balances, menu) +// } +} diff --git a/app/src/main/res/drawable/ic_merchants.xml b/app/src/main/res/drawable/ic_merchants.xml index 806e675..094456f 100644 --- a/app/src/main/res/drawable/ic_merchants.xml +++ b/app/src/main/res/drawable/ic_merchants.xml @@ -1,9 +1,12 @@ - + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml index ace746c..a219c09 100644 --- a/app/src/main/res/drawable/ic_settings.xml +++ b/app/src/main/res/drawable/ic_settings.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_transactions.xml b/app/src/main/res/drawable/ic_transactions.xml new file mode 100644 index 0000000..060c0e5 --- /dev/null +++ b/app/src/main/res/drawable/ic_transactions.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_balances.xml b/app/src/main/res/layout/fragment_balances.xml index 364b34c..f41c657 100644 --- a/app/src/main/res/layout/fragment_balances.xml +++ b/app/src/main/res/layout/fragment_balances.xml @@ -35,20 +35,6 @@ tools:listitem="@layout/item_balance" tools:itemCount="3"/> - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_transactions.xml b/app/src/main/res/layout/fragment_transactions.xml new file mode 100644 index 0000000..d80ebb6 --- /dev/null +++ b/app/src/main/res/layout/fragment_transactions.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_balances.xml b/app/src/main/res/menu/menu_balances.xml index f1094e0..f9d5c72 100644 --- a/app/src/main/res/menu/menu_balances.xml +++ b/app/src/main/res/menu/menu_balances.xml @@ -2,6 +2,12 @@ + + diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index 966e57e..73c210a 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -12,7 +12,16 @@ android:label="@string/app_name" tools:layout="@layout/fragment_balances"> - + + + + \ No newline at end of file From 6e25dd7589193923c59ff1f98c056b83d4aeec4d Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 13 Dec 2018 10:16:57 -0600 Subject: [PATCH 066/129] Create new Balances layout with the send and receive buttons at the top and the user balances at the bottom per Ken's design. --- app/src/main/AndroidManifest.xml | 1 + .../fragments/BalancesFragment.kt | 4 +- app/src/main/res/drawable/ic_receive.xml | 16 +- app/src/main/res/drawable/ic_send.xml | 12 +- app/src/main/res/layout/fragment_balances.xml | 162 ++++++++++++++---- 5 files changed, 143 insertions(+), 52 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 914a868..ee829b5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,6 +29,7 @@ > { balancesDetails -> balancesAdapter.replaceAll(balancesDetails) diff --git a/app/src/main/res/drawable/ic_receive.xml b/app/src/main/res/drawable/ic_receive.xml index 8b18a9d..1967adf 100644 --- a/app/src/main/res/drawable/ic_receive.xml +++ b/app/src/main/res/drawable/ic_receive.xml @@ -1,9 +1,7 @@ - - - + + diff --git a/app/src/main/res/drawable/ic_send.xml b/app/src/main/res/drawable/ic_send.xml index 9dd0116..312dfa5 100644 --- a/app/src/main/res/drawable/ic_send.xml +++ b/app/src/main/res/drawable/ic_send.xml @@ -1,9 +1,5 @@ - - + + diff --git a/app/src/main/res/layout/fragment_balances.xml b/app/src/main/res/layout/fragment_balances.xml index f41c657..dcd4724 100644 --- a/app/src/main/res/layout/fragment_balances.xml +++ b/app/src/main/res/layout/fragment_balances.xml @@ -1,40 +1,134 @@ - + + + android:layout_height="0dp" + android:layout_weight="1" + android:elevation="8dp"> - - - - - - - + android:layout_height="match_parent"> - + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 22666021f188efb2f8657140a3fe5db14626934f Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 13 Dec 2018 11:24:18 -0600 Subject: [PATCH 067/129] - Add Navigation's SafeArgs plugin to the project, this plugin enables to pass arguments between fragments in a safe way. - Use the Navigation AAC to create the navigation from the Balances to the Send and Receive fragments, using Navigation's SafeArgs to activate the camera in SendTransactionFragment in the case the user tapped on the camera button instead ofjust the send button in the Balances. --- app/build.gradle | 2 +- .../fragments/BalancesFragment.kt | 23 ++++++++++--- .../fragments/SendTransactionFragment.kt | 5 ++- app/src/main/res/layout/fragment_balances.xml | 1 - .../main/res/navigation/mobile_navigation.xml | 32 +++++++++++++++++++ build.gradle | 1 + 6 files changed, 57 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b01f760..555ae82 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.application' +apply plugin: "androidx.navigation.safeargs" apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' @@ -52,7 +53,6 @@ dependencies { implementation "android.arch.navigation:navigation-fragment-ktx:$nav_version" implementation "android.arch.navigation:navigation-ui-ktx:$nav_version" - implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' implementation 'org.bitcoinj:bitcoinj-core:0.14.3' diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt index 955aa12..2d3fed9 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt @@ -6,19 +6,17 @@ import android.preference.PreferenceManager import android.view.* import androidx.fragment.app.Fragment import androidx.lifecycle.Observer +import androidx.navigation.Navigation +import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.adapters.BalancesAdapter -import cy.agorise.bitsybitshareswallet.adapters.TransfersDetailsAdapter import cy.agorise.bitsybitshareswallet.database.entities.UserAccount import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail -import cy.agorise.bitsybitshareswallet.database.joins.TransferDetail import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel -import cy.agorise.bitsybitshareswallet.viewmodels.TransferDetailViewModel import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel import kotlinx.android.synthetic.main.fragment_balances.* @@ -60,6 +58,23 @@ class BalancesFragment : Fragment() { mBalanceDetailViewModel.getAll().observe(this, Observer> { balancesDetails -> balancesAdapter.replaceAll(balancesDetails) }) + + // Navigate to the Receive Transaction Fragment + fabReceiveTransaction.setOnClickListener ( + Navigation.createNavigateOnClickListener(R.id.receive_action) + ) + + // Navigate to the Send Transaction Fragment without activating the camera + fabSendTransaction.setOnClickListener( + Navigation.createNavigateOnClickListener(R.id.send_action) + ) + + // Navigate to the Send Transaction Fragment using Navigation's SafeArgs to activate the camera + fabSendTransactionCamera.setOnClickListener { + val action = BalancesFragmentDirections.sendActionCamera() + action.setOpenCamera(true) + findNavController().navigate(action) + } } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt index 0bc7c24..93a52f9 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt @@ -122,7 +122,10 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv if (userId != "") mUserAccount = UserAccount(userId) - verifyCameraPermission() + // Use Navigation SafeArgs to decide if we should activate or not the camera feed + val safeArgs = SendTransactionFragmentArgs.fromBundle(arguments) + if (safeArgs.openCamera) + verifyCameraPermission() fabOpenCamera.setOnClickListener { if (isCameraPreviewVisible) stopCameraPreview() else verifyCameraPermission() } diff --git a/app/src/main/res/layout/fragment_balances.xml b/app/src/main/res/layout/fragment_balances.xml index dcd4724..d19c24a 100644 --- a/app/src/main/res/layout/fragment_balances.xml +++ b/app/src/main/res/layout/fragment_balances.xml @@ -54,7 +54,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" app:fabSize="mini" - app:maxImageSize="18dp" android:src="@drawable/ic_camera" android:backgroundTint="@color/colorSend" app:layout_constraintTop_toTopOf="parent" diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index 73c210a..c00a28f 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -11,6 +11,19 @@ android:name="cy.agorise.bitsybitshareswallet.fragments.BalancesFragment" android:label="@string/app_name" tools:layout="@layout/fragment_balances"> + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index ff630b8..c22b77e 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0-alpha08" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From 1565bab28c5b2b1005133e411a724a041394a43a Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 13 Dec 2018 11:49:57 -0600 Subject: [PATCH 068/129] Improve Transactions' cards UI. --- app/src/main/res/layout/fragment_transactions.xml | 2 ++ app/src/main/res/layout/item_transaction.xml | 4 ++-- app/src/main/res/values/dimens.xml | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/fragment_transactions.xml b/app/src/main/res/layout/fragment_transactions.xml index d80ebb6..d895dc3 100644 --- a/app/src/main/res/layout/fragment_transactions.xml +++ b/app/src/main/res/layout/fragment_transactions.xml @@ -9,6 +9,8 @@ android:id="@+id/rvTransactions" android:layout_width="match_parent" android:layout_height="wrap_content" + android:padding="@dimen/card_margin" + android:clipToPadding="false" tools:listitem="@layout/item_transaction" tools:itemCount="6"/> diff --git a/app/src/main/res/layout/item_transaction.xml b/app/src/main/res/layout/item_transaction.xml index c042a15..967998c 100644 --- a/app/src/main/res/layout/item_transaction.xml +++ b/app/src/main/res/layout/item_transaction.xml @@ -8,8 +8,8 @@ android:layout_height="wrap_content" android:layout_gravity="center" card_view:cardElevation="4dp" - card_view:cardCornerRadius="4dp" - android:layout_margin="4dp"> + card_view:cardCornerRadius="@dimen/card_radius" + android:layout_margin="@dimen/card_margin"> 180dp + + 4dp + 4dp + From 5a6b098f38663959b9c4c87bf521f3d161615b41 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 13 Dec 2018 12:34:42 -0600 Subject: [PATCH 069/129] Replaced SettingsActivity with SettingsFragmet and created the Navigation methods to hook the Balances' Settings toolbar icon with the Settings fragment so it automatically opens when the icon is tapped. --- app/src/main/AndroidManifest.xml | 3 - .../activities/SettingsActivity.kt | 65 ------------------- .../fragments/SettingsFragment.kt | 48 ++++++++++++++ ...ity_settings.xml => fragment_settings.xml} | 2 +- .../main/res/navigation/mobile_navigation.xml | 6 ++ app/src/main/res/values/strings.xml | 23 +++++-- 6 files changed, 72 insertions(+), 75 deletions(-) delete mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SettingsActivity.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt rename app/src/main/res/layout/{activity_settings.xml => fragment_settings.xml} (98%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ee829b5..0e21e22 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -31,9 +31,6 @@ android:theme="@style/Theme.Bitsy.NoActionBar" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan"/> - \ No newline at end of file diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SettingsActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SettingsActivity.kt deleted file mode 100644 index 0c8a014..0000000 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/SettingsActivity.kt +++ /dev/null @@ -1,65 +0,0 @@ -package cy.agorise.bitsybitshareswallet.activities - -import android.os.Bundle -import android.preference.PreferenceManager -import android.view.MenuItem -import androidx.appcompat.app.AppCompatActivity -import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.utils.Constants -import kotlinx.android.synthetic.main.activity_settings.* - -/** - * A simple activity for the user to select his preferences - */ -class SettingsActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - // TODO move the below to a BaseActivity to apply it to all activities - // Sets the theme to night mode if it has been selected by the user - if (PreferenceManager.getDefaultSharedPreferences(this) - .getBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, false) - ) { - setTheme(R.style.Theme_Bitsy_Dark) - } - - setContentView(R.layout.activity_settings) - - setupActionBar() - - initNightModeSwitch() - } - - /** - * Set up the [android.app.ActionBar], if the API is available. - */ - private fun setupActionBar() { - supportActionBar?.setDisplayHomeAsUpEnabled(true) - } - - private fun initNightModeSwitch() { - val nightModeOn = PreferenceManager.getDefaultSharedPreferences(this) - .getBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, false) - - switchNightMode.isChecked = nightModeOn - - switchNightMode.setOnCheckedChangeListener { buttonView, isChecked -> - - PreferenceManager.getDefaultSharedPreferences(buttonView.context).edit() - .putBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, isChecked).apply() - - // Recreates the activity to apply the selected theme - this.recreate() - } - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (item.itemId == android.R.id.home) { - onBackPressed() - return true - } - return super.onOptionsItemSelected(item) - } - -} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt new file mode 100644 index 0000000..f191b54 --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt @@ -0,0 +1,48 @@ +package cy.agorise.bitsybitshareswallet.fragments + +import android.os.Bundle +import android.preference.PreferenceManager +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.utils.Constants +import kotlinx.android.synthetic.main.fragment_settings.* + +class SettingsFragment : Fragment() { + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + setHasOptionsMenu(true) + + return inflater.inflate(R.layout.fragment_settings, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initNightModeSwitch() + } + + private fun initNightModeSwitch() { + val nightModeOn = PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, false) + + switchNightMode.isChecked = nightModeOn + + switchNightMode.setOnCheckedChangeListener { buttonView, isChecked -> + + PreferenceManager.getDefaultSharedPreferences(buttonView.context).edit() + .putBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, isChecked).apply() + + // Recreates the activity to apply the selected theme + // TODO find a way to automatically change the theme + // this.recreate() + } + } +} + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/fragment_settings.xml similarity index 98% rename from app/src/main/res/layout/activity_settings.xml rename to app/src/main/res/layout/fragment_settings.xml index d014e87..b2ca929 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -9,7 +9,7 @@ android:paddingEnd="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="32dp" - tools:context=".activities.SettingsActivity"> + tools:context=".fragments.SettingsFragment"> + + BiTSy -

                  

BiTSy Terms and Conditions of Use

 

BiTSy is a software Application (also known as an “App”) developed by the International Business Company “AGORISE, LTD.”, which has been established under Cypriot law. Any person wishing to use this App is obliged to accept the following Terms and Conditions of Use, before any such use:

 

Part I - Terminology

 

The following Terminology applies to these Terms and Conditions of Use (hereinafter referred to as “Terms”), the Privacy and Transparency Statement, and all other agreements between You and Us:

  • The terms “Client”, “Customer”, “Merchant”, “User”, “You” and “Your” refer to you, the person accessing the BiTSy software Application (hereinafter referred to as “App”) and hereby accepting our Terms.
  • The terms “Agorise”, “The Company”, “Our”, “Ourselves”, “We” and “Us” collectively refer to the App and to its owners, freelancers, developers, designers, contractors, directors, officers, employees, agents, insurers, suppliers, and attorneys.
  • The term “Party” refers to either You or Us.
  • In all the above-mentioned Terms, unless otherwise specified, words using the singular include the plural and vice versa and words using gender include all genders.
  • The terms “digital asset”, “asset”, “coin”, “cryptocurrency”, “ledger entry”, “altcoin” and “token” refer to blockchain-based software ledger data entries.
  • The term “Blockchain” refers to a chain of blocks, processed by hundreds of computers around the world. A blockchain (like “Bitshares”) is a decentralized network of computers, an immutable distributed ledger. As each block of transactions is confirmed every 3 (three) seconds, it is hashed together with the latest block in the chain, forming the next block in the chain. Hence the term blockchain.
  • The term “Ledger” refers to a digital version of the “big book” of blocks of transactions taking place on a blockchain. The Distributed ledger keeps track of all transactions on a blockchain network.
  • The name “Morphit” refers to the name chosen by our Company for the Bridge.
  • The term “Bridge” refers to a company or autonomous software (like the “Morphit” feature of our App) which converts/morphs one cryptocurrency into another by way of seeking the best possible price for the Customer by using various third-party exchanges.
  • The terms “Teller” or “Gateway” refers to a person or company (or autonomous software) that converts “fiat” (USD, EUR, CNY, etc) into cryptocurrencies, and vice-versa, whether by cash, card, Swift or SEPA, etc.
  • The term “Multisig” refers to Multiple Signatories. Multiple people or accounts that are assigned to validate a transaction before it can be allowed to be processed, and entered into a block on the chain. Typically, two or more people sign the transaction with their private key (Public Key Infrastructure (PKI)) which will approve the transaction to be sent.
  • For the term “Bitshares” more information can usually be found at the website: http://www.bitshares.org
  • The term “Coin” refers to a digital token. It is underlined that this term is still loosely defined in legislation. It’s a unit of value (if it has any value at all, as determined by the free market) which is running on a blockchain.
  • The term “BTS” refers to the core token that the Bitshares platform uses to determine fair-market values for tokens.

 

Part II - Terms and Conditions of Use

 

By using the App, you represent and warrant that you are:

  1. at least 18 (eighteen) years old and have full capacity to contract under the applicable law;
  2. only transacting with the App with legally-obtained funds that belong to you;
  3. not furthering, performing, undertaking, engaging in, aiding, or abetting any unlawful activity through your relationship with Us or through your use of the App (for example: money laundering, etc); and,
  4. comporting with and obeying all applicable laws.

 

We reserve the right to terminate your access to the App for any breach or our Terms, in our sole and absolute discretion, if the App ceases to exist and/or following a decision of the Company. Use of the App is void where prohibited by applicable law.

 

1. Terms

 

1.1 By accessing the App, you agree to be bound by our Terms, all applicable laws and regulations in Cyprus, and you agree that you are responsible for compliance with, and that you are compliant with applicable law.

 

1.2 If you do not agree with any of our Terms, you are prohibited from using or accessing the App. Your only recourse is to stop using the App. Any use of the App after accepting these Terms is considered to be a deemed acceptance of our Terms, as they may be modified and amended from time to time.

 

1.3 The materials contained in the App are protected by applicable copyright and trademark laws in Cyprus and EU and international treaties. The updates of our Terms, as they appear on our website, take into account the legislative modifications.

 

1.4 By accepting our Terms, you expressly accept that data of transactions made when accessing the App might be exported outside the jurisdiction in which you reside or are located when you access the App. This export is an inherent part of our App and is necessary for its functioning and does not include personal data of Users in any way.

 

1.5 By using any of the third-parties linked to within the App (such as Tellers or Gateways), it is not an endorsement of those third-parties, nor is it a guarantee of any kind that using those third-parties will not result in loss of funds or other damages. Use those third-parties at your own risk.

 

2. Limitations

 

The use of this App may carry financial risk for any User, and is to be used as an experimental software utility only. In no event shall We be liable or responsible for any damages, claims, applications, losses, injuries, delays, accidents, costs, business interruption costs, or other expenses (including, without limitation, attorneys’ fees or the costs of any claim or suit), nor for any incidental, direct, general, indirect, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, loss of cryptocurrency or digital assets, work stoppage, computer or device failure or malfunction, or any other commercial or other losses directly or indirectly arising out of or related to:

  1. our Terms;
  2. the Privacy and Transparency Statement;
  3. any service We provide;
  4. the use of the App;
  5. any use of your digital assets or cryptocurrency with the App by any other party not authorized by you (collectively, all of the foregoing items shall be referred to herein as “Losses”).

 

We are hereby released by You from liability for any kind of the above-mentioned Losses. We disclaim any and all warranties or guarantees, including any warranty of merchantability and warranty of fitness for any particular purpose.

 

The foregoing limitations of liability shall apply whether the alleged liability or Losses are based on contract, negligence, tort, strict liability, or any other basis, even if We have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of other remedies. Notwithstanding anything else in our Terms, in no event shall the combined aggregate liability for any Loss hereunder exceed € 50.00 (fifty euros).

 

3. Prices, Exchange Rates, Surety and Confirmations

 

3.1 Users are hereby informed that Cryptocurrencies and digital assets in general are highly experimental and risky. Our App attempts to provide accurate price and exchange rate information, but this information is as well highly volatile and can change quickly without Users or Us necessarily being aware of these changes.

 

3.2 The exchange rate that the Customer pays (if applicable) is calculated at the moment the App presents the amount due to the customer (via the QR Code or NFC signal). Our App will always seek out the best price for the Customer.

3.3 The confirmation time of some cryptocurrencies can be very lengthy. For example, if a customer pays with a slow coin such as the Petro (Venezuela) but pays a minimal miner fee when sending their funds to the App, then that customer’s payment may not be processed by that network for many hours, if at all.

 

Due to this risk, the App offers a Surety feature, allowing You to voluntarily pre-fund a Multisig blockchain account (for example: joes-grocery-morphit) with some Bitshares (BTS) tokens, and then voluntarily share that account with the Morphit bridge algorithm in the App temporarily.

 

This way, the bridge can send the necessary BTS or smartcoins to the Merchant instantly, be protected from customer minimal miner fee or double-spend scams, and confirm the customers "completed" payment so that the customer doesn't have to stand there waiting for their (slow coin) payment to confirm. The customer can then theoretically pay with any supported coin and leave in as little as 3 seconds. Payments in a Bitshares token do not require use of a bridge or surety at all since that chain is so fast. Steem payments don't need surety either, but the bridge is used real quick to convert it to the merchants desired BTS or smartcoin. The merchant can empty their surety account any time they like, or add more funds to it for high volume (such as grocery chains) or larger transactions (such as homes or cars).

 

If however, the customer’s payment is never confirmed by their network, then that amount of Surety that was shared with the bridge will not be released back to You. The bridge will not assume any risk of Your customers payments not clearing.

 

Due to individual blockchain specifications, the Customer payment is typically considered “accepted” by the bridge at two block confirmations. If a bridge had to be used, the bridge will then automatically release the Surety back to you that was shared while the bridge was awaiting those two block confirmations. It is important to note that a payment being broadcast to a blockchain network does not constitute an acceptance by the App of that payment.

 

4. Returns and Refund Policy

 

4.1 Cryptocurrencies, tokens, and digital assets are, by their nature, generally irreversible, and their exchange rates are highly volatile and transitory. Once the User’s asset has been transmitted to the User’s address, no refund is possible, even if the wrong address was provided to the App. All sales after transmission are final and the Company is not in position to reverse or correct the process already undertaken by the App.

 

4.2 Surety can be 100% refunded at any time from within the App itself. With no pre-funded bridge Surety however, only EOS or Graphene-based cryptocurrencies should be accepted (such as Steem and/or Bitshares tokens).

 

5. Governing Law

 

5.1 These Terms are governed by the laws of Cyprus, and any and all laws applicable therein.

 

5.2 Our Terms are to be treated in all respects as a Cypriot contract. We and You irrevocably and unconditionally attorn to the non-exclusive jurisdiction, venue and forum of the courts of Nicosia, Cyprus, and all courts competent to hear appeals therefrom.

 

6. Permissible Use 

 

The App and all its services may be used only as a mechanism of software ledger entry translation between the User and the Bitshares blockchain. You are prohibited from using the App for the purpose of translating ledger entries with other parties, with the exception of explicit payment for goods and services.

 

7. Terms of Use Modifications 

 

7.1 We may revise our Terms at any time and without notice to you or third parties. By using the App, you agree to be bound by the then-current version of our Terms. All modifications generally apply ex nunc, unless otherwise specified in special cases, if this is justified by the circumstances.

 

7.2 The Terms as they appear on the website of our App are always up-to-date. Therefore, Users are advised to visit the relevant part of the website regularly in order to be informed of the latest changes.

 

8. Costs 

 

8.1 From time to time, We may need to spend time dealing with issues brought to Us by customers, for example requests of information.

 

8.2 Where any customer issue is not caused by our negligence or oversight, We reserve the right to recover reasonable administrative costs spent addressing the customer issue. These costs will be calculated by the Company taking into account the relevant administrative burden caused to it and will be communicated to the Customer.

 

8.3 No response will be sent to the Customer if this entails a payment from his side, before the cost is communicated to him by the email provided by him for this specific purpose.

 

9. Transparency Statement 

 

9.1 No personal data whatsoever of Users is registered, stored or processed in any way; Users are solely liable for keeping the “key” which is necessary to access the interface and in case of loss renders this access impossible. Therefore, the Regulation (EU) No 2016/679 (GDPR) is not applicable within the framework of this App.

 

9.2 We also do not in any way obscure the information that it does request or obtain. Due to the inherent transparency of blockchains, transactions to and from the App are public and easily correlated. Utilizing the App to obscure transactions or assets in any way is futile. Law enforcement has full access to blockchain information that goes in or out of the Bitshares network.

 

9.3 You accept that We will comply willingly with all legal requests for information from it. We reserve the right to provide information to law enforcement personnel and other third parties to answer inquiries; to respond to legal process; to respond to the order of a court of competent jurisdiction and those exercising the court’s authority; and, to protect Ourselves and our users.

 

Copyright 2018 AGORISE, LTD.

An International Business Co.

Cyprus Reg# HE375959

 

IF YOU AGREE TO ALL OF THESE TERMS AND CONDITIONS, PLEASE TAP ON THE GREEN BUTTON BELOW

]]>
+ +

                  

BiTSy Terms and Conditions of Use

 

BiTSy is a software Application (also known as an “App”) developed by the International Business Company “AGORISE, LTD.”, which has been established under Cypriot law. Any person wishing to use this App is obliged to accept the following Terms and Conditions of Use, before any such use:

 

Part I - Terminology

 

The following Terminology applies to these Terms and Conditions of Use (hereinafter referred to as “Terms”), the Privacy and Transparency Statement, and all other agreements between You and Us:

  • The terms “Client”, “Customer”, “Merchant”, “User”, “You” and “Your” refer to you, the person accessing the BiTSy software Application (hereinafter referred to as “App”) and hereby accepting our Terms.
  • The terms “Agorise”, “The Company”, “Our”, “Ourselves”, “We” and “Us” collectively refer to the App and to its owners, freelancers, developers, designers, contractors, directors, officers, employees, agents, insurers, suppliers, and attorneys.
  • The term “Party” refers to either You or Us.
  • In all the above-mentioned Terms, unless otherwise specified, words using the singular include the plural and vice versa and words using gender include all genders.
  • The terms “digital asset”, “asset”, “coin”, “cryptocurrency”, “ledger entry”, “altcoin” and “token” refer to blockchain-based software ledger data entries.
  • The term “Blockchain” refers to a chain of blocks, processed by hundreds of computers around the world. A blockchain (like “Bitshares”) is a decentralized network of computers, an immutable distributed ledger. As each block of transactions is confirmed every 3 (three) seconds, it is hashed together with the latest block in the chain, forming the next block in the chain. Hence the term blockchain.
  • The term “Ledger” refers to a digital version of the “big book” of blocks of transactions taking place on a blockchain. The Distributed ledger keeps track of all transactions on a blockchain network.
  • The name “Morphit” refers to the name chosen by our Company for the Bridge.
  • The term “Bridge” refers to a company or autonomous software (like the “Morphit” feature of our App) which converts/morphs one cryptocurrency into another by way of seeking the best possible price for the Customer by using various third-party exchanges.
  • The terms “Teller” or “Gateway” refers to a person or company (or autonomous software) that converts “fiat” (USD, EUR, CNY, etc) into cryptocurrencies, and vice-versa, whether by cash, card, Swift or SEPA, etc.
  • The term “Multisig” refers to Multiple Signatories. Multiple people or accounts that are assigned to validate a transaction before it can be allowed to be processed, and entered into a block on the chain. Typically, two or more people sign the transaction with their private key (Public Key Infrastructure (PKI)) which will approve the transaction to be sent.
  • For the term “Bitshares” more information can usually be found at the website: http://www.bitshares.org
  • The term “Coin” refers to a digital token. It is underlined that this term is still loosely defined in legislation. It’s a unit of value (if it has any value at all, as determined by the free market) which is running on a blockchain.
  • The term “BTS” refers to the core token that the Bitshares platform uses to determine fair-market values for tokens.

 

Part II - Terms and Conditions of Use

 

By using the App, you represent and warrant that you are:

  1. at least 18 (eighteen) years old and have full capacity to contract under the applicable law;
  2. only transacting with the App with legally-obtained funds that belong to you;
  3. not furthering, performing, undertaking, engaging in, aiding, or abetting any unlawful activity through your relationship with Us or through your use of the App (for example: money laundering, etc); and,
  4. comporting with and obeying all applicable laws.

 

We reserve the right to terminate your access to the App for any breach or our Terms, in our sole and absolute discretion, if the App ceases to exist and/or following a decision of the Company. Use of the App is void where prohibited by applicable law.

 

1. Terms

 

1.1 By accessing the App, you agree to be bound by our Terms, all applicable laws and regulations in Cyprus, and you agree that you are responsible for compliance with, and that you are compliant with applicable law.

 

1.2 If you do not agree with any of our Terms, you are prohibited from using or accessing the App. Your only recourse is to stop using the App. Any use of the App after accepting these Terms is considered to be a deemed acceptance of our Terms, as they may be modified and amended from time to time.

 

1.3 The materials contained in the App are protected by applicable copyright and trademark laws in Cyprus and EU and international treaties. The updates of our Terms, as they appear on our website, take into account the legislative modifications.

 

1.4 By accepting our Terms, you expressly accept that data of transactions made when accessing the App might be exported outside the jurisdiction in which you reside or are located when you access the App. This export is an inherent part of our App and is necessary for its functioning and does not include personal data of Users in any way.

 

1.5 By using any of the third-parties linked to within the App (such as Tellers or Gateways), it is not an endorsement of those third-parties, nor is it a guarantee of any kind that using those third-parties will not result in loss of funds or other damages. Use those third-parties at your own risk.

 

2. Limitations

 

The use of this App may carry financial risk for any User, and is to be used as an experimental software utility only. In no event shall We be liable or responsible for any damages, claims, applications, losses, injuries, delays, accidents, costs, business interruption costs, or other expenses (including, without limitation, attorneys’ fees or the costs of any claim or suit), nor for any incidental, direct, general, indirect, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, loss of cryptocurrency or digital assets, work stoppage, computer or device failure or malfunction, or any other commercial or other losses directly or indirectly arising out of or related to:

  1. our Terms;
  2. the Privacy and Transparency Statement;
  3. any service We provide;
  4. the use of the App;
  5. any use of your digital assets or cryptocurrency with the App by any other party not authorized by you (collectively, all of the foregoing items shall be referred to herein as “Losses”).

 

We are hereby released by You from liability for any kind of the above-mentioned Losses. We disclaim any and all warranties or guarantees, including any warranty of merchantability and warranty of fitness for any particular purpose.

 

The foregoing limitations of liability shall apply whether the alleged liability or Losses are based on contract, negligence, tort, strict liability, or any other basis, even if We have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of other remedies. Notwithstanding anything else in our Terms, in no event shall the combined aggregate liability for any Loss hereunder exceed € 50.00 (fifty euros).

 

3. Prices, Exchange Rates, Surety and Confirmations

 

3.1 Users are hereby informed that Cryptocurrencies and digital assets in general are highly experimental and risky. Our App attempts to provide accurate price and exchange rate information, but this information is as well highly volatile and can change quickly without Users or Us necessarily being aware of these changes.

 

3.2 The exchange rate that the Customer pays (if applicable) is calculated at the moment the App presents the amount due to the customer (via the QR Code or NFC signal). Our App will always seek out the best price for the Customer.

3.3 The confirmation time of some cryptocurrencies can be very lengthy. For example, if a customer pays with a slow coin such as the Petro (Venezuela) but pays a minimal miner fee when sending their funds to the App, then that customer’s payment may not be processed by that network for many hours, if at all.

 

Due to this risk, the App offers a Surety feature, allowing You to voluntarily pre-fund a Multisig blockchain account (for example: joes-grocery-morphit) with some Bitshares (BTS) tokens, and then voluntarily share that account with the Morphit bridge algorithm in the App temporarily.

 

This way, the bridge can send the necessary BTS or smartcoins to the Merchant instantly, be protected from customer minimal miner fee or double-spend scams, and confirm the customers "completed" payment so that the customer doesn't have to stand there waiting for their (slow coin) payment to confirm. The customer can then theoretically pay with any supported coin and leave in as little as 3 seconds. Payments in a Bitshares token do not require use of a bridge or surety at all since that chain is so fast. Steem payments don't need surety either, but the bridge is used real quick to convert it to the merchants desired BTS or smartcoin. The merchant can empty their surety account any time they like, or add more funds to it for high volume (such as grocery chains) or larger transactions (such as homes or cars).

 

If however, the customer’s payment is never confirmed by their network, then that amount of Surety that was shared with the bridge will not be released back to You. The bridge will not assume any risk of Your customers payments not clearing.

 

Due to individual blockchain specifications, the Customer payment is typically considered “accepted” by the bridge at two block confirmations. If a bridge had to be used, the bridge will then automatically release the Surety back to you that was shared while the bridge was awaiting those two block confirmations. It is important to note that a payment being broadcast to a blockchain network does not constitute an acceptance by the App of that payment.

 

4. Returns and Refund Policy

 

4.1 Cryptocurrencies, tokens, and digital assets are, by their nature, generally irreversible, and their exchange rates are highly volatile and transitory. Once the User’s asset has been transmitted to the User’s address, no refund is possible, even if the wrong address was provided to the App. All sales after transmission are final and the Company is not in position to reverse or correct the process already undertaken by the App.

 

4.2 Surety can be 100% refunded at any time from within the App itself. With no pre-funded bridge Surety however, only EOS or Graphene-based cryptocurrencies should be accepted (such as Steem and/or Bitshares tokens).

 

5. Governing Law

 

5.1 These Terms are governed by the laws of Cyprus, and any and all laws applicable therein.

 

5.2 Our Terms are to be treated in all respects as a Cypriot contract. We and You irrevocably and unconditionally attorn to the non-exclusive jurisdiction, venue and forum of the courts of Nicosia, Cyprus, and all courts competent to hear appeals therefrom.

 

6. Permissible Use 

 

The App and all its services may be used only as a mechanism of software ledger entry translation between the User and the Bitshares blockchain. You are prohibited from using the App for the purpose of translating ledger entries with other parties, with the exception of explicit payment for goods and services.

 

7. Terms of Use Modifications 

 

7.1 We may revise our Terms at any time and without notice to you or third parties. By using the App, you agree to be bound by the then-current version of our Terms. All modifications generally apply ex nunc, unless otherwise specified in special cases, if this is justified by the circumstances.

 

7.2 The Terms as they appear on the website of our App are always up-to-date. Therefore, Users are advised to visit the relevant part of the website regularly in order to be informed of the latest changes.

 

8. Costs 

 

8.1 From time to time, We may need to spend time dealing with issues brought to Us by customers, for example requests of information.

 

8.2 Where any customer issue is not caused by our negligence or oversight, We reserve the right to recover reasonable administrative costs spent addressing the customer issue. These costs will be calculated by the Company taking into account the relevant administrative burden caused to it and will be communicated to the Customer.

 

8.3 No response will be sent to the Customer if this entails a payment from his side, before the cost is communicated to him by the email provided by him for this specific purpose.

 

9. Transparency Statement 

 

9.1 No personal data whatsoever of Users is registered, stored or processed in any way; Users are solely liable for keeping the “key” which is necessary to access the interface and in case of loss renders this access impossible. Therefore, the Regulation (EU) No 2016/679 (GDPR) is not applicable within the framework of this App.

 

9.2 We also do not in any way obscure the information that it does request or obtain. Due to the inherent transparency of blockchains, transactions to and from the App are public and easily correlated. Utilizing the App to obscure transactions or assets in any way is futile. Law enforcement has full access to blockchain information that goes in or out of the Bitshares network.

 

9.3 You accept that We will comply willingly with all legal requests for information from it. We reserve the right to provide information to law enforcement personnel and other third parties to answer inquiries; to respond to legal process; to respond to the order of a court of competent jurisdiction and those exercising the court’s authority; and, to protect Ourselves and our users.

 

Copyright 2018 AGORISE, LTD.

An International Business Co.

Cyprus Reg# HE375959

 

IF YOU AGREE TO ALL OF THESE TERMS AND CONDITIONS, PLEASE TAP ON THE GREEN BUTTON BELOW

]]>
Agree @@ -10,7 +11,9 @@ Loading Assets… - Performing a series of requests in order to get the complete list of all existing assets + Performing a series of requests in order to get the complete list of all + existing assets + Loaded %1$d assets into the database Assets Loaded Next, please setup your account… @@ -22,14 +25,18 @@ Confirm PIN PIN mismatch BrainKey - Please enter correct brainkey, it should have between 12 and 16 words. + Please enter correct brainkey, it should have between 12 and 16 + words. + Import Create Invalid account, please check your brainkey for typing errors Please try again after 5 minutes Please select an account - The keys derived from this brainkey seem to be used to control more than one account, please select which account you wish to import + The keys derived from this brainkey seem to be used to control + more than one account, please select which account you wish to import + MainActivity @@ -56,9 +63,13 @@ Automatically close BiTSy after 3 minutes of inactivity Night mode Backup - BrainKey. Account recovery words that can be captured or copied, but not edited. + BrainKey. Account recovery words that can be captured or copied, but not + edited. + Bugs or Ideas? - Telegram chat: http://t.me/Agorise\nEmail: Agorise@protonmail.ch\nOpen Source: https://github.com/Agorise + Telegram chat: http://t.me/Agorise\nEmail: Agorise@protonmail.ch\nOpen Source: + https://github.com/Agorise + From ffebc39bcf12dd6ea64023516b5d35a57d085eaf Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 13 Dec 2018 12:47:25 -0600 Subject: [PATCH 070/129] Add Send/Receive text below the Send/Receive buttons in the Balances screen and improve its layout so they are always centered both vertically and horizontally. --- app/src/main/res/layout/fragment_balances.xml | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/layout/fragment_balances.xml b/app/src/main/res/layout/fragment_balances.xml index d19c24a..4a8da69 100644 --- a/app/src/main/res/layout/fragment_balances.xml +++ b/app/src/main/res/layout/fragment_balances.xml @@ -45,9 +45,22 @@ android:backgroundTint="@color/colorReceive" android:src="@drawable/ic_receive" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toStartOf="@id/firstVerticalGuideline"/> + app:layout_constraintEnd_toStartOf="@id/firstVerticalGuideline" + app:layout_constraintBottom_toTopOf="@+id/tvReceiveTransaction" + app:layout_constraintVertical_chainStyle="packed"/> + + @@ -71,9 +84,22 @@ android:backgroundTint="@color/colorSend" android:src="@drawable/ic_send" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toEndOf="@id/secondVerticalGuideline" - app:layout_constraintEnd_toEndOf="parent"/> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toTopOf="@+id/tvSendTransaction" + app:layout_constraintVertical_chainStyle="packed"/> + + Date: Thu, 13 Dec 2018 13:10:19 -0600 Subject: [PATCH 071/129] Add methods to automatically change the theme to night mode when the user selects it and also avoid a crash in the TransfersLoader. --- .../bitsybitshareswallet/activities/MainActivity.kt | 7 +++++++ .../bitsybitshareswallet/fragments/SettingsFragment.kt | 3 +-- .../bitsybitshareswallet/processors/TransfersLoader.kt | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 52160f9..d968721 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -2,6 +2,7 @@ package cy.agorise.bitsybitshareswallet.activities import android.content.res.Resources import android.os.Bundle +import android.preference.PreferenceManager import android.view.MenuItem import androidx.navigation.findNavController import androidx.navigation.fragment.NavHostFragment @@ -10,6 +11,7 @@ import androidx.navigation.ui.navigateUp import androidx.navigation.ui.onNavDestinationSelected import androidx.navigation.ui.setupActionBarWithNavController import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.graphenej.api.ConnectionStatusUpdate import cy.agorise.graphenej.models.JsonRpcResponse import kotlinx.android.synthetic.main.activity_main.* @@ -21,6 +23,11 @@ class MainActivity : ConnectedActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + // Sets the theme to night mode if it has been selected by the user + if (PreferenceManager.getDefaultSharedPreferences(this) + .getBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, false)) { + setTheme(R.style.Theme_Bitsy_Dark_NoActionBar) + } setContentView(R.layout.activity_main) setSupportActionBar(toolbar) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt index f191b54..327e77a 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt @@ -40,8 +40,7 @@ class SettingsFragment : Fragment() { .putBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, isChecked).apply() // Recreates the activity to apply the selected theme - // TODO find a way to automatically change the theme - // this.recreate() + activity?.recreate() } } } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt index be4c5b7..3cca418 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt @@ -155,7 +155,7 @@ class TransfersLoader(private var mContext: Context?): ServiceConnection { } override fun onServiceDisconnected(name: ComponentName?) { - + mShouldUnbindNetwork = false } override fun onServiceConnected(name: ComponentName?, service: IBinder?) { From f45d9055c3c60ffdb12b868e9f79a08005f4c3a8 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 13 Dec 2018 14:29:32 -0600 Subject: [PATCH 072/129] Add functionality to the Settings 'Automatically close BiTSy after 3 minutes of inactivity', the user selection is saved into the SharedPreferences and if it happens to be true then the app will close when that time amount of inactivity happens. --- .../activities/MainActivity.kt | 38 +++++++++++++++---- .../fragments/SettingsFragment.kt | 14 +++++++ .../bitsybitshareswallet/utils/Constants.kt | 11 +++--- app/src/main/res/layout/fragment_settings.xml | 2 +- 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index d968721..92a619a 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -1,7 +1,7 @@ package cy.agorise.bitsybitshareswallet.activities -import android.content.res.Resources import android.os.Bundle +import android.os.Handler import android.preference.PreferenceManager import android.view.MenuItem import androidx.navigation.findNavController @@ -21,6 +21,10 @@ class MainActivity : ConnectedActivity() { private lateinit var appBarConfiguration : AppBarConfiguration + // Handler and Runnable used to add a timer for user inaction and close the app if enough time has passed + private lateinit var mHandler: Handler + private lateinit var mRunnable: Runnable + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Sets the theme to night mode if it has been selected by the user @@ -42,13 +46,33 @@ class MainActivity : ConnectedActivity() { setupActionBarWithNavController(navController, appBarConfiguration) - navController.addOnDestinationChangedListener { _, destination, _ -> - val dest: String = try { - resources.getResourceName(destination.id) - } catch (e: Resources.NotFoundException) { - Integer.toString(destination.id) - } + mHandler = Handler() + mRunnable = Runnable { + if (PreferenceManager.getDefaultSharedPreferences(this) + .getBoolean(Constants.KEY_AUTO_CLOSE_ACTIVATED, false)) + finish() + else + restartHandler() } + startHandler() + } + + override fun onUserInteraction() { + super.onUserInteraction() + restartHandler() + } + + private fun restartHandler() { + stopHandler() + startHandler() + } + + private fun stopHandler() { + mHandler.removeCallbacks(mRunnable) + } + + private fun startHandler() { + mHandler.postDelayed(mRunnable, 3 * 60 * 1000) //for 3 minutes } override fun onOptionsItemSelected(item: MenuItem): Boolean { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt index 327e77a..42728f4 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt @@ -25,9 +25,23 @@ class SettingsFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + initAutoCloseSwitch() + initNightModeSwitch() } + private fun initAutoCloseSwitch() { + val autoCloseOn = PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(Constants.KEY_AUTO_CLOSE_ACTIVATED, false) + + switchAutoClose.isChecked = autoCloseOn + + switchAutoClose.setOnCheckedChangeListener { buttonView, isChecked -> + PreferenceManager.getDefaultSharedPreferences(buttonView.context).edit() + .putBoolean(Constants.KEY_AUTO_CLOSE_ACTIVATED, isChecked).apply() + } + } + private fun initNightModeSwitch() { val nightModeOn = PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, false) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt index 1226d68..990228d 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt @@ -44,16 +44,15 @@ object Constants { */ const val MISSING_PAYMENT_CHECK_PERIOD: Long = 5000 - /** - * Time period to wait to send a request to the NetworkService, and retry in case it is still not connected - */ + /** Time period to wait to send a request to the NetworkService, and retry in case it is still not connected */ const val NETWORK_SERVICE_RETRY_PERIOD: Long = 5000 - /** - * Key used to store the number of operations that the currently selected account had last time we checked - */ + /** Key used to store the number of operations that the currently selected account had last time we checked */ const val KEY_ACCOUNT_OPERATION_COUNT = "key_account_operation_count" + /** Key used to store the auto close app if no user activity setting into the shared preferences */ + const val KEY_AUTO_CLOSE_ACTIVATED = "key_auto_close_activated" + /** Key used to store the night mode setting into the shared preferences */ const val KEY_NIGHT_MODE_ACTIVATED = "key_night_mode_activated" } diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index b2ca929..11a1402 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -19,7 +19,7 @@ android:textStyle="bold"/> Date: Thu, 13 Dec 2018 16:01:26 -0600 Subject: [PATCH 073/129] - Update the MaterialDialogs library version. - Add the functionality to the Settings BrainKey's View & Show button. It first fetches the brainkey from the authorities db table and then shows it in a custom MaterialDialog so that the user can view and copy it. --- app/build.gradle | 2 +- .../activities/MainActivity.kt | 13 +++- .../database/daos/AuthorityDao.kt | 3 + .../fragments/SettingsFragment.kt | 75 +++++++++++++++++++ .../processors/TransfersLoader.kt | 6 +- .../repositories/AuthorityRepository.kt | 4 + .../main/res/layout/dialog_copy_brainkey.xml | 11 +++ app/src/main/res/values/strings.xml | 2 + 8 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 app/src/main/res/layout/dialog_copy_brainkey.xml diff --git a/app/build.gradle b/app/build.gradle index 555ae82..8e116b7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,7 +59,7 @@ dependencies { implementation 'com.moldedbits.r2d2:r2d2:1.0.1' implementation 'com.google.zxing:core:3.3.1' implementation 'me.dm7.barcodescanner:zxing:1.9.8' - implementation 'com.afollestad.material-dialogs:core:2.0.0-rc1' + implementation 'com.afollestad.material-dialogs:core:2.0.0-rc3' // Android Debug Database debugImplementation 'com.amitshekhar.android:debug-db:1.0.4' diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 92a619a..6cebcf7 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -39,14 +39,19 @@ class MainActivity : ConnectedActivity() { val host: NavHostFragment = supportFragmentManager .findFragmentById(R.id.navHostFragment) as NavHostFragment? ?: return - // Set up Action Bar + // Set up Action Bar with Navigation's controller val navController = host.navController appBarConfiguration = AppBarConfiguration(navController.graph) + // Sets up the ActionBar with the navigation controller so that it automatically responds to clicks on toolbar + // menu items and shows the up navigation button on all fragments except home (Balances) setupActionBarWithNavController(navController, appBarConfiguration) mHandler = Handler() + + // When this runnable finishes it first verifies if the auto close feature is enabled and if it is then it + // closes the app, if not then it just restarts the Handler (timer) mRunnable = Runnable { if (PreferenceManager.getDefaultSharedPreferences(this) .getBoolean(Constants.KEY_AUTO_CLOSE_ACTIVATED, false)) @@ -57,11 +62,17 @@ class MainActivity : ConnectedActivity() { startHandler() } + /** + * Restarts the Handler (timer) each time there is user's interaction + */ override fun onUserInteraction() { super.onUserInteraction() restartHandler() } + /** + * Stops and then restarts the Handler + */ private fun restartHandler() { stopHandler() startHandler() diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AuthorityDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AuthorityDao.kt index 5956e15..fecff8c 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AuthorityDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AuthorityDao.kt @@ -12,6 +12,9 @@ interface AuthorityDao { @Insert fun insert(authority: Authority) + @Query("SELECT * FROM authorities WHERE user_id=:userId LIMIT 1") + fun get(userId: String): Single + @Query("SELECT * FROM authorities") fun getAll(): LiveData> diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt index 42728f4..94ab336 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SettingsFragment.kt @@ -1,17 +1,31 @@ package cy.agorise.bitsybitshareswallet.fragments +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context.CLIPBOARD_SERVICE import android.os.Bundle import android.preference.PreferenceManager import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.fragment.app.Fragment +import com.afollestad.materialdialogs.MaterialDialog +import com.afollestad.materialdialogs.customview.customView import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.repositories.AuthorityRepository import cy.agorise.bitsybitshareswallet.utils.Constants +import cy.agorise.bitsybitshareswallet.utils.CryptoUtils +import cy.agorise.graphenej.BrainKey +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.schedulers.Schedulers import kotlinx.android.synthetic.main.fragment_settings.* class SettingsFragment : Fragment() { + private val TAG = this.javaClass.simpleName + private var mDisposables = CompositeDisposable() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -28,8 +42,14 @@ class SettingsFragment : Fragment() { initAutoCloseSwitch() initNightModeSwitch() + + btnViewBrainKey.setOnClickListener { getBrainkey(it) } } + /** + * Fetches the relevant preference from the SharedPreferences and configures the corresponding switch accordingly, + * and adds a listener to the said switch to store the preference in case the user changes it. + */ private fun initAutoCloseSwitch() { val autoCloseOn = PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(Constants.KEY_AUTO_CLOSE_ACTIVATED, false) @@ -42,6 +62,11 @@ class SettingsFragment : Fragment() { } } + /** + * Fetches the relevant preference from the SharedPreferences and configures the corresponding switch accordingly, + * and adds a listener to the said switch to store the preference in case the user changes it. Also makes a call to + * recreate the activity and apply the selected theme. + */ private fun initNightModeSwitch() { val nightModeOn = PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(Constants.KEY_NIGHT_MODE_ACTIVATED, false) @@ -57,5 +82,55 @@ class SettingsFragment : Fragment() { activity?.recreate() } } + + /** + * Obtains the brainKey from the authorities db table for the current user account and if it is not null it passes + * the brainKey to a method to show it in a nice MaterialDialog + */ + private fun getBrainkey(view: View) { + val userId = PreferenceManager.getDefaultSharedPreferences(view.context) + .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") ?: "" + + val authorityRepository = AuthorityRepository(view.context) + + mDisposables.add(authorityRepository.get(userId) + .subscribeOn(Schedulers.computation()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { authority -> + if (authority != null) { + val plainBrainKey = CryptoUtils.decrypt(view.context, authority.encryptedBrainKey) + val plainSequenceNumber = CryptoUtils.decrypt(view.context, authority.encryptedSequenceNumber) + val sequenceNumber = Integer.parseInt(plainSequenceNumber) + val brainKey = BrainKey(plainBrainKey, sequenceNumber) + showBrainKeyDialog(view, brainKey) + } + } + ) + } + + /** + * Shows the plain brainkey in a dialog so that the user can view and Copy it. + */ + private fun showBrainKeyDialog(view: View, brainKey: BrainKey) { + MaterialDialog(view.context).show { + title(text = "BrainKey") + message(text = brainKey.brainKey) + customView(R.layout.dialog_copy_brainkey) + cancelable(false) + positiveButton(android.R.string.copy) { + Toast.makeText(it.context, "Copied to clipboard", Toast.LENGTH_SHORT).show() + val clipboard = it.context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText("label", brainKey.brainKey) + clipboard.primaryClip = clip + it.dismiss() + } + } + } + + override fun onDestroy() { + super.onDestroy() + + if (!mDisposables.isDisposed) mDisposables.dispose() + } } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt index 3cca418..13255b7 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt @@ -122,7 +122,8 @@ class TransfersLoader(private var mContext: Context?): ServiceConnection { Log.e(TAG, "AEADBadTagException. Class: " + e.javaClass + ", Msg: " + e.message) } - }) + } + ) mDisposables.add(RxBus.getBusInstance() .asFlowable() .observeOn(AndroidSchedulers.mainThread()) @@ -145,7 +146,8 @@ class TransfersLoader(private var mContext: Context?): ServiceConnection { responseMap.clear() } } - })) + }) + ) } else { // If there is no current user, we should not do anything mState = State.CANCELLED diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AuthorityRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AuthorityRepository.kt index 46ad1f3..e241170 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AuthorityRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AuthorityRepository.kt @@ -20,6 +20,10 @@ class AuthorityRepository internal constructor(context: Context) { insertAsyncTask(mAuthorityDao).execute(authority) } + fun get(userId: String): Single { + return mAuthorityDao.get(userId) + } + fun getWIF(userId: String, authorityType: Int): Single { return mAuthorityDao.getWIF(userId, authorityType) } diff --git a/app/src/main/res/layout/dialog_copy_brainkey.xml b/app/src/main/res/layout/dialog_copy_brainkey.xml new file mode 100644 index 0000000..f4d31a9 --- /dev/null +++ b/app/src/main/res/layout/dialog_copy_brainkey.xml @@ -0,0 +1,11 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 273049e..469970f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -66,6 +66,8 @@ BrainKey. Account recovery words that can be captured or copied, but not edited. + Print this out, or write it down. Anyone with access to your recovery key will + have access to funds within this wallet. Bugs or Ideas? Telegram chat: http://t.me/Agorise\nEmail: Agorise@protonmail.ch\nOpen Source: From dd290a4b2c93b36701ad7c89fed91b8e02386fc3 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Thu, 13 Dec 2018 16:57:58 -0600 Subject: [PATCH 074/129] Improve Balances' Material cards to show nice elevation with shadows. --- app/src/main/res/layout/fragment_balances.xml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/layout/fragment_balances.xml b/app/src/main/res/layout/fragment_balances.xml index 4a8da69..e810658 100644 --- a/app/src/main/res/layout/fragment_balances.xml +++ b/app/src/main/res/layout/fragment_balances.xml @@ -4,18 +4,18 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" - android:layout_marginTop="@dimen/activity_vertical_margin" - android:layout_marginBottom="@dimen/activity_vertical_margin" - android:layout_marginStart="@dimen/activity_horizontal_margin" - android:layout_marginEnd="@dimen/activity_horizontal_margin" android:orientation="vertical" tools:context=".fragments.BalancesFragment"> + android:layout_marginTop="@dimen/activity_vertical_margin" + android:layout_marginStart="@dimen/activity_horizontal_margin" + android:layout_marginEnd="@dimen/activity_horizontal_margin" + app:cardElevation="4dp"> + app:cardElevation="4dp"> Date: Thu, 13 Dec 2018 20:21:03 -0600 Subject: [PATCH 075/129] Create the menus for Balances and Net Worth that make use of a customized TabLayout and a ViewPager to obtain the desired effect. - Created custom themed attribute colorBackgroundFocusable to assign the correct background color to the balances and net worth tabs. - Renamed BalancesFragment to HomeFragment because, the BalancesFragment will now only be used to display the Balances in the above mentioned ViewPager. --- .../fragments/BalancesFragment.kt | 83 ----------- .../fragments/HomeFragment.kt | 139 ++++++++++++++++++ ...ragment_balances.xml => fragment_home.xml} | 48 ++++-- .../main/res/navigation/mobile_navigation.xml | 8 +- app/src/main/res/values/attr.xml | 5 + app/src/main/res/values/colors.xml | 3 + app/src/main/res/values/styles.xml | 4 + 7 files changed, 187 insertions(+), 103 deletions(-) delete mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/HomeFragment.kt rename app/src/main/res/layout/{fragment_balances.xml => fragment_home.xml} (81%) create mode 100644 app/src/main/res/values/attr.xml diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt deleted file mode 100644 index 2d3fed9..0000000 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/BalancesFragment.kt +++ /dev/null @@ -1,83 +0,0 @@ -package cy.agorise.bitsybitshareswallet.fragments - -import androidx.lifecycle.ViewModelProviders -import android.os.Bundle -import android.preference.PreferenceManager -import android.view.* -import androidx.fragment.app.Fragment -import androidx.lifecycle.Observer -import androidx.navigation.Navigation -import androidx.navigation.fragment.findNavController -import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.LinearLayoutManager - -import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.adapters.BalancesAdapter -import cy.agorise.bitsybitshareswallet.database.entities.UserAccount -import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail -import cy.agorise.bitsybitshareswallet.utils.Constants -import cy.agorise.bitsybitshareswallet.viewmodels.BalanceDetailViewModel -import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel -import kotlinx.android.synthetic.main.fragment_balances.* - -class BalancesFragment : Fragment() { - - private lateinit var mUserAccountViewModel: UserAccountViewModel - private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - setHasOptionsMenu(true) - - return inflater.inflate(R.layout.fragment_balances, container, false) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - // Configure UserAccountViewModel to show the current account - mUserAccountViewModel = ViewModelProviders.of(this).get(UserAccountViewModel::class.java) - - val userId = PreferenceManager.getDefaultSharedPreferences(context) - .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") - - mUserAccountViewModel.getUserAccount(userId!!).observe(this, Observer{ user -> - tvAccountName.text = user.name - }) - - // Configure BalanceDetailViewModel to show the current balances - mBalanceDetailViewModel = ViewModelProviders.of(this).get(BalanceDetailViewModel::class.java) - - val balancesAdapter = BalancesAdapter(context!!) - rvBalances.adapter = balancesAdapter - rvBalances.layoutManager = LinearLayoutManager(context!!) - rvBalances.addItemDecoration(DividerItemDecoration(context!!, DividerItemDecoration.VERTICAL)) - - mBalanceDetailViewModel.getAll().observe(this, Observer> { balancesDetails -> - balancesAdapter.replaceAll(balancesDetails) - }) - - // Navigate to the Receive Transaction Fragment - fabReceiveTransaction.setOnClickListener ( - Navigation.createNavigateOnClickListener(R.id.receive_action) - ) - - // Navigate to the Send Transaction Fragment without activating the camera - fabSendTransaction.setOnClickListener( - Navigation.createNavigateOnClickListener(R.id.send_action) - ) - - // Navigate to the Send Transaction Fragment using Navigation's SafeArgs to activate the camera - fabSendTransactionCamera.setOnClickListener { - val action = BalancesFragmentDirections.sendActionCamera() - action.setOpenCamera(true) - findNavController().navigate(action) - } - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.menu_balances, menu) - } -} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/HomeFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/HomeFragment.kt new file mode 100644 index 0000000..bb113ae --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/HomeFragment.kt @@ -0,0 +1,139 @@ +package cy.agorise.bitsybitshareswallet.fragments + +import androidx.lifecycle.ViewModelProviders +import android.os.Bundle +import android.preference.PreferenceManager +import android.view.* +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentPagerAdapter +import androidx.lifecycle.Observer +import androidx.navigation.Navigation +import androidx.navigation.fragment.findNavController + +import cy.agorise.bitsybitshareswallet.R +import cy.agorise.bitsybitshareswallet.database.entities.UserAccount +import cy.agorise.bitsybitshareswallet.utils.Constants +import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel +import kotlinx.android.synthetic.main.fragment_home.* +import kotlinx.android.synthetic.main.item_balance.view.* + +class HomeFragment : Fragment() { + + private lateinit var mUserAccountViewModel: UserAccountViewModel +// private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + setHasOptionsMenu(true) + + return inflater.inflate(R.layout.fragment_home, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // Configure UserAccountViewModel to show the current account + mUserAccountViewModel = ViewModelProviders.of(this).get(UserAccountViewModel::class.java) + + val userId = PreferenceManager.getDefaultSharedPreferences(context) + .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") + + mUserAccountViewModel.getUserAccount(userId!!).observe(this, Observer{ user -> + tvAccountName.text = user.name + }) + +// // Configure BalanceDetailViewModel to show the current balances +// mBalanceDetailViewModel = ViewModelProviders.of(this).get(BalanceDetailViewModel::class.java) +// +// val balancesAdapter = BalancesAdapter(context!!) +// rvBalances.adapter = balancesAdapter +// rvBalances.layoutManager = LinearLayoutManager(context!!) +// rvBalances.addItemDecoration(DividerItemDecoration(context!!, DividerItemDecoration.VERTICAL)) +// +// mBalanceDetailViewModel.getAll().observe(this, Observer> { balancesDetails -> +// balancesAdapter.replaceAll(balancesDetails) +// }) + + // Navigate to the Receive Transaction Fragment + fabReceiveTransaction.setOnClickListener ( + Navigation.createNavigateOnClickListener(R.id.receive_action) + ) + + // Navigate to the Send Transaction Fragment without activating the camera + fabSendTransaction.setOnClickListener( + Navigation.createNavigateOnClickListener(R.id.send_action) + ) + + // Navigate to the Send Transaction Fragment using Navigation's SafeArgs to activate the camera + fabSendTransactionCamera.setOnClickListener { + val action = HomeFragmentDirections.sendActionCamera() + action.setOpenCamera(true) + findNavController().navigate(action) + } + + val pagerAdapter = PagerAdapter(fragmentManager!!) + viewPager.adapter = pagerAdapter + tabLayout.setupWithViewPager(viewPager) + } + + /** + * Pager adapter to create the placeholder fragments + */ + private inner class PagerAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm) { + + override fun getItem(position: Int): Fragment { + // getItem is called to instantiate the fragment for the given page. + // Return a PlaceholderFragment (defined as a static inner class below). + return PlaceholderFragment.newInstance(position + 1) + } + + override fun getPageTitle(position: Int): CharSequence? { + return listOf(getString(R.string.title_balances), "Net Worth")[position] + } + + override fun getCount(): Int { + return 2 + } + } + + /** + * A placeholder fragment containing a simple view. + */ + class PlaceholderFragment : Fragment() { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + val rootView = inflater.inflate(R.layout.item_balance, container, false) + val text = "Hello World from section ${arguments?.getInt(ARG_SECTION_NUMBER)}" + rootView.tvBalance.text = text + return rootView + } + + companion object { + /** + * The fragment argument representing the section number for this + * fragment. + */ + private const val ARG_SECTION_NUMBER = "section_number" + + /** + * Returns a new instance of this fragment for the given section + * number. + */ + fun newInstance(sectionNumber: Int): PlaceholderFragment { + val fragment = PlaceholderFragment() + val args = Bundle() + args.putInt(ARG_SECTION_NUMBER, sectionNumber) + fragment.arguments = args + return fragment + } + } + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_balances, menu) + } +} diff --git a/app/src/main/res/layout/fragment_balances.xml b/app/src/main/res/layout/fragment_home.xml similarity index 81% rename from app/src/main/res/layout/fragment_balances.xml rename to app/src/main/res/layout/fragment_home.xml index e810658..839c71a 100644 --- a/app/src/main/res/layout/fragment_balances.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" - tools:context=".fragments.BalancesFragment"> + tools:context=".fragments.HomeFragment"> - - - + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:background="?attr/themedColorBackgroundFloating" + app:tabSelectedTextColor="?android:textColorPrimary" + app:tabIndicatorColor="?android:colorControlHighlight" + app:tabIndicatorHeight="50dp" + app:tabMode="scrollable" /> + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index 0779d6c..b6a9619 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -4,13 +4,13 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mobile_navigation" - app:startDestination="@id/balancesFragment"> + app:startDestination="@id/home_dest"> + tools:layout="@layout/fragment_home"> + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index cce4962..05a6f26 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -4,6 +4,9 @@ #006ba4 #0099d6 + + #424242 + #000 #888 #e0e0e0 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c8b8039..62b84b9 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -6,6 +6,8 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent + + @android:color/white