Skip to content

Commit

Permalink
Updated BitBay exchange to Zonda
Browse files Browse the repository at this point in the history
Added 1inch, Fantom, Gala, Kava, and The Sandbox coins.
Updated default refresh interval to 15 minutes.
Refresh coin lists.
  • Loading branch information
hwki committed Feb 17, 2022
1 parent 723ef08 commit 82480c9
Show file tree
Hide file tree
Showing 27 changed files with 91 additions and 60 deletions.
14 changes: 7 additions & 7 deletions bitcoin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId "com.brentpanther.bitcoinwidget"
minSdk 23
targetSdk 31
versionCode 294
versionName "8.2"
versionCode 295
versionName "8.2.1"

javaCompileOptions {
annotationProcessorOptions {
Expand Down Expand Up @@ -68,13 +68,13 @@ dependencies {
implementation "androidx.core:core-ktx:1.7.0"
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
implementation 'androidx.fragment:fragment-ktx:1.4.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.4.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.4.1'
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.google.android.material:material:1.5.0'
Expand Down
7 changes: 7 additions & 0 deletions bitcoin/src/main/java/com/brentpanther/bitcoinwidget/Coin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import java.util.*
enum class Coin(val coinName: String, vararg val themes: IconTheme) : Parcelable {

CUSTOM("Custom", IconTheme(SOLID, ic_placeholder)),
ONE_INCH("1inch", IconTheme(SOLID, ic_1inch)),
AAVE("Aave", IconTheme(SOLID, ic_aave)),
ADA("Cardano", IconTheme(SOLID, ic_ada)),
ALGO("Algorand", IconTheme(SOLID, ic_algo, ic_algo_white)),
Expand Down Expand Up @@ -59,7 +60,9 @@ enum class Coin(val coinName: String, vararg val themes: IconTheme) : Parcelable
ETH("Ethereum", IconTheme(SOLID, ic_eth)),
FIL("Filecoin", IconTheme(SOLID, ic_fil)),
FIRO("Firo", IconTheme(SOLID, ic_firo, ic_firo_dark)),
FTM("Fantom", IconTheme(SOLID, ic_ftm)),
FTT("FTX Token", IconTheme(SOLID, ic_ftt)),
GALA("Gala", IconTheme(SOLID, ic_gala, ic_gala_white)),
GNO("Gnosis", IconTheme(SOLID, ic_gno_color)),
GNT("Golem", IconTheme(SOLID, ic_gnt_blue)),
GRIN("Grin", IconTheme(SOLID, ic_grin_color_black)),
Expand All @@ -69,6 +72,7 @@ enum class Coin(val coinName: String, vararg val themes: IconTheme) : Parcelable
HT("Huobi Token", IconTheme(SOLID, ic_ht)),
ICX("Icon", IconTheme(SOLID, ic_icx)),
IOTA("Iota", IconTheme(SOLID, ic_iota, ic_iota_white)),
KAVA("Kava", IconTheme(SOLID, ic_kava)),
KMD("Komodo", IconTheme(SOLID, ic_kmd)),
KNC("Kyber Network", IconTheme(SOLID, ic_knc_color)),
KSM("Kusama", IconTheme(SOLID, ic_ksm_black, ic_ksm_white)),
Expand Down Expand Up @@ -105,6 +109,7 @@ enum class Coin(val coinName: String, vararg val themes: IconTheme) : Parcelable
REP("Augur", IconTheme(SOLID, ic_rep)),
RUNE("THORChain", IconTheme(SOLID, ic_rune)),
RVN("Ravencoin", IconTheme(SOLID, ic_rvn)),
SAND("The Sandbox", IconTheme(SOLID, ic_sand)),
SHIB("Shiba Inu", IconTheme(SOLID, ic_shib)),
SNX("Synthetix Network Token", IconTheme(SOLID, ic_snx)),
SOL("Solana", IconTheme(SOLID, ic_sol)),
Expand Down Expand Up @@ -139,6 +144,8 @@ enum class Coin(val coinName: String, vararg val themes: IconTheme) : Parcelable
return if (dark) iconTheme.dark else iconTheme.light
}

fun getSymbol() = if (this == ONE_INCH) "1INCH" else name

companion object {

internal var COIN_NAMES: SortedSet<String> = values().map { it.name }.toSortedSet(String.CASE_INSENSITIVE_ORDER)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.brentpanther.bitcoinwidget.db

import android.util.Log
import androidx.sqlite.db.SupportSQLiteDatabase
import com.brentpanther.bitcoinwidget.exchange.Exchange

object DataMigration {

private val TAG = DataMigration::class.java.simpleName

fun migrate(db: SupportSQLiteDatabase) {
migrateBitBayToZonda(db)
fixRemovedExchanges(db)
}

private fun migrateBitBayToZonda(db: SupportSQLiteDatabase) {
db.execSQL("UPDATE Widget SET exchange = 'ZONDA' WHERE exchange = 'BITBAY'")
}

private fun fixRemovedExchanges(db: SupportSQLiteDatabase) {
val cursor = db.query("SELECT id, exchange FROM Widget ORDER BY id")
val allExchanges = Exchange.values().map { it.name }
val errored = mutableListOf<Int>()
while (cursor.moveToNext()) {
val exchange = cursor.getString(1)
if (!allExchanges.contains(exchange)) {
val id = cursor.getInt(0)
errored.add(id)
Log.w(TAG, "Widget $id: has invalid exchange: $exchange")
}
}
// fallback to coingecko for any broken exchange
for (id in errored) {
db.execSQL("UPDATE Widget SET exchange = 'COINGECKO' WHERE id = $id")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ object DatabaseInitializer {
put("showAmountLabel", false)
put("useInverse", false)
put("widgetType", WidgetType.PRICE.name)
minRefresh = min(minRefresh, getString(obj, "refresh")?.toInt() ?: 30)
minRefresh = min(minRefresh, getString(obj, "refresh")?.toInt() ?: 15)
}
db.insert("widget", CONFLICT_REPLACE, values)
} catch (e: Exception) {
Log.e(TAG, "Exception caught when migrating to database.", e)
}
}
val values = ContentValues().apply {
put("refresh", if(minRefresh == Int.MAX_VALUE) 30 else minRefresh)
put("refresh", if(minRefresh == Int.MAX_VALUE) 15 else minRefresh)
put("consistentSize", globalPrefs.getBoolean("fixed_size", false))
put("dataMigrationVersion", 1)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ data class Widget(
var lastUpdated: Long,
var state: WidgetState
) {
fun toCoinEntry() = CoinEntry(coinCustomId ?: coin.coinName, coinName(), coin.name, coin, customIcon)
fun toCoinEntry() = CoinEntry(coinCustomId ?: coin.coinName, coinName(), coin.getSymbol(), coin, customIcon)

fun coinName() = if (coinCustomId != null) coinCustomName ?: coin.coinName else coin.coinName

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ abstract class WidgetDatabase : RoomDatabase() {

companion object {

private val TAG = WidgetDatabase::class.java.simpleName

private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Widget ADD COLUMN widgetType TEXT NOT NULL DEFAULT 'PRICE'")
Expand Down Expand Up @@ -72,7 +70,7 @@ abstract class WidgetDatabase : RoomDatabase() {
}

override fun onOpen(db: SupportSQLiteDatabase) {
fixRemovedExchanges(db)
DataMigration.migrate(db)
super.onOpen(db)
}
}
Expand All @@ -89,23 +87,7 @@ abstract class WidgetDatabase : RoomDatabase() {
}
}

private fun fixRemovedExchanges(db: SupportSQLiteDatabase) {
val cursor = db.query("SELECT id, exchange FROM Widget ORDER BY id")
val allExchanges = Exchange.values().map { it.name }
val errored = mutableListOf<Int>()
while (cursor.moveToNext()) {
val exchange = cursor.getString(1)
if (!allExchanges.contains(exchange)) {
val id = cursor.getInt(0)
errored.add(id)
Log.w(TAG, "Widget $id: has invalid exchange: $exchange")
}
}
// fallback to coingecko for any broken exchange
for (id in errored) {
db.execSQL("UPDATE Widget SET exchange = 'COINGECKO' WHERE id = $id")
}
}

}
}

Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@ enum class Exchange(val exchangeName: String, shortName: String? = null) {
return getJsonObject(url).getAsJsonObject("data").get("last").asString
}
},
BITBAY("BitBay") {

override fun getValue(coin: String, currency: String): String {
val url = "https://api.bitbay.net/rest/trading/ticker/$coin-$currency"
return getJsonObject(url).getAsJsonObject("ticker").get("rate").asString
}
},
BITCAMBIO("BitCambio") {

override fun getValue(coin: String, currency: String): String {
Expand Down Expand Up @@ -274,6 +267,7 @@ enum class Exchange(val exchangeName: String, shortName: String? = null) {
override fun getValue(coin: String, currency: String): String? {
// hardcoded map to id
val map = mapOf(
"1INCH" to "1inch",
"AAVE" to "aave",
"ADA" to "cardano",
"ALGO" to "algorand",
Expand Down Expand Up @@ -313,7 +307,9 @@ enum class Exchange(val exchangeName: String, shortName: String? = null) {
"ETH" to "ethereum",
"FIL" to "filecoin",
"FIRO" to "zcoin",
"FTM" to "fantom",
"FTT" to "ftx-token",
"GALA" to "gala",
"GNO" to "gnosis",
"GNT" to "golem",
"GRIN" to "grin",
Expand All @@ -323,6 +319,7 @@ enum class Exchange(val exchangeName: String, shortName: String? = null) {
"HT" to "huobi-token",
"ICX" to "icon",
"IOTA" to "iota",
"KAVA" to "kava",
"KMD" to "komodo",
"KNC" to "kyber-network",
"KSM" to "kusama",
Expand Down Expand Up @@ -355,6 +352,7 @@ enum class Exchange(val exchangeName: String, shortName: String? = null) {
"REP" to "augur",
"RUNE" to "thorchain",
"RVN" to "ravencoin",
"SAND" to "the-sandbox",
"SHIB" to "shiba-inu",
"SNX" to "havven",
"SOL" to "solana",
Expand Down Expand Up @@ -761,6 +759,12 @@ enum class Exchange(val exchangeName: String, shortName: String? = null) {
val url = "https://kline.zbg.com/api/data/v1/ticker?marketName=$pair"
return getJsonObject(url).getAsJsonArray("datas")[1].asString
}
},
ZONDA("Zonda") {
override fun getValue(coin: String, currency: String): String {
val url = "https://api.zonda.exchange/rest/trading/ticker/$coin-$currency"
return getJsonObject(url).getAsJsonObject("ticker").get("rate").asString
}
};

val shortName: String = shortName ?: exchangeName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ open class ExchangeData(val coinEntry: CoinEntry, json: InputStream) {

init {
this.obj = Gson().fromJson(InputStreamReader(json), JsonExchangeObject::class.java)
loadCurrencies(coinEntry.coin.name)
loadCurrencies(coinEntry.coin.getSymbol())
}

// only return currencies that we know about
Expand Down Expand Up @@ -101,7 +101,7 @@ open class ExchangeData(val coinEntry: CoinEntry, json: InputStream) {
}

open fun getExchangeCoinName(exchange: String): String? {
return obj?.getExchangeCoinName(exchange, coinEntry.coin.name)
return obj?.getExchangeCoinName(exchange, coinEntry.coin.getSymbol())
}

open fun getExchangeCurrencyName(exchange: String, currency: String): String? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ open class PriceWidgetDataStrategy(context: Context, widgetId: Int) : WidgetData
}
try {
val currency = widget.currencyCustomName ?: widget.currency
val coin = widget.coinCustomId ?: widget.coinCustomName ?: widget.coin.name
val coin = widget.coinCustomId ?: widget.coinCustomName ?: widget.coin.getSymbol()
val value = widget.exchange.getValue(coin, currency)
widget.state = WidgetState.CURRENT
if (value == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ open class BaseManageSettingsFragment : PreferenceFragmentCompat() {

override fun putString(key: String?, value: String?) {
when(key) {
"refresh_interval" -> config.refresh = value?.toInt() ?: 30
"refresh_interval" -> config.refresh = value?.toInt() ?: 15
}
viewModel.updateGlobalSettings(config)
WidgetProvider.refreshWidgets(requireContext(), restart = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class WidgetAdapter(private val onClickListener: ((settings: WidgetSettings) ->

// need to find at runtime since view hierarchy updated after binding
binding.root.findViewById<View>(R.id.parent).isClickable = false
val coinName = widget.coinUnit ?: widget.coinCustomName ?: widget.coin.name
val coinName = widget.coinUnit ?: widget.coinCustomName ?: widget.coin.getSymbol()
val price = binding.root.findViewById<TextView>(R.id.price)
TextViewCompat.setAutoSizeTextTypeWithDefaults(price, TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM)
binding.labelType.text = root.context.getString(widget.widgetType.widgetName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ class CoinSelectionActivity : AppCompatActivity() {
coinSelected(it, false)
}
binding.coinList.adapter = adapter
viewModel.coins.observe(this, {
viewModel.coins.observe(this) {
adapter.coins = it
adapter.notifyItemRangeInserted(adapter.coins.count(), it.count())
})
}
binding.search.doAfterTextChanged(adapter.filter::filter)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class CoinSelectionViewModel(application: Application) : AndroidViewModel(applic

private var allCoins = Coin.values().filterNot { it == Coin.CUSTOM }.associateBy { it.name }
private var fullCoins: List<CoinEntry> = allCoins.map {
CoinEntry(it.key, it.value.coinName, it.key, it.value)
CoinEntry(it.key, it.value.coinName, it.value.getSymbol(), it.value)
}.sortedWith { o1, o2 ->
String.CASE_INSENSITIVE_ORDER.compare(o1.coin.coinName, o2.coin.coinName)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import com.brentpanther.bitcoinwidget.exchange.Exchange
import com.brentpanther.bitcoinwidget.exchange.ExchangeData
import com.brentpanther.bitcoinwidget.exchange.ExchangeHelper
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collect
import java.io.ByteArrayOutputStream
import java.io.File
import java.text.DecimalFormat
Expand Down
Binary file added bitcoin/src/main/res/drawable-nodpi/ic_1inch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added bitcoin/src/main/res/drawable-nodpi/ic_ftm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added bitcoin/src/main/res/drawable-nodpi/ic_gala.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added bitcoin/src/main/res/drawable-nodpi/ic_kava.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added bitcoin/src/main/res/drawable-nodpi/ic_sand.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion bitcoin/src/main/res/raw/cryptowidgetcoins_v2.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bitcoin/src/main/res/raw/othercoins.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bitcoin/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
<item>ISO</item>
<item>NONE</item>
</string-array>
<string name="json_last_modified" translatable="false">Thu, 03 Feb 2022 22:22:11 GMT</string>
<string name="json_last_modified" translatable="false">Thu, 17 Feb 2022 16:32:00 GMT</string>
<string name="json_url" translatable="false">https://www.brentpanther.com/cryptowidgetcoins_v2.json</string>

<string name="settings_updating_data">Updating coin data…</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ class ExchangeTest {
val coins = EnumSet.allOf(Coin::class.java).sorted()
for (coin in coins) {
println("Checking $coin")
val entry = CoinEntry(coin.name, coin.coinName, coin.name, coin)
val entry = CoinEntry(coin.name, coin.coinName, coin.getSymbol(), coin)
val data = ExchangeData(entry, loadJSON())
for (currency in data.currencies.sorted()) {
for (exchange in data.getExchanges(currency).toList().parallelStream()) {
try {
var coinName = data.getExchangeCoinName(exchange)
var currencyName = data.getExchangeCurrencyName(exchange, currency)
if (coinName == null) coinName = coin.name
if (coinName == null) coinName = coin.getSymbol()
if (currencyName == null) currencyName = currency
valueOf(exchange).getValue(coinName, currencyName)!!.toDouble()
} catch (e: Exception) {
Expand Down
Loading

0 comments on commit 82480c9

Please sign in to comment.