mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-26 08:55:56 +01:00
Merge branch 'widgerref' into modal
This commit is contained in:
commit
a076b3ec39
6 changed files with 136 additions and 86 deletions
|
@ -118,8 +118,8 @@ dependencies {
|
|||
// The version of react-native is set by the React Native Gradle Plugin
|
||||
implementation("com.facebook.react:react-android")
|
||||
implementation files("../../node_modules/rn-ldk/android/libs/LDK-release.aar")
|
||||
implementation 'androidx.core:core-ktx:1.13.1'
|
||||
implementation 'androidx.core:core-remoteviews:1.1.0'
|
||||
implementation 'androidx.core:core-ktx'
|
||||
implementation 'androidx.work:work-runtime-ktx:2.7.1'
|
||||
|
||||
if (hermesEnabled.toBoolean()) {
|
||||
implementation("com.facebook.react:hermes-android")
|
||||
|
@ -131,8 +131,6 @@ dependencies {
|
|||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'com.google.android.material:material:1.4.0'
|
||||
implementation "androidx.work:work-runtime:2.9.0"
|
||||
implementation "androidx.work:work-runtime-ktx:2.9.0"
|
||||
}
|
||||
apply plugin: 'com.google.gms.google-services' // Google Services plugin
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@ class BitcoinPriceWidget : AppWidgetProvider() {
|
|||
WorkManager.getInstance(context).cancelUniqueWork(WidgetUpdateWorker.WORK_NAME)
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
override fun onReceive(context: Context, intent:Intent) {
|
||||
super.onReceive(context, intent)
|
||||
Log.d("BitcoinPriceWidget", "onReceive called with action: ${intent.action}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,47 +46,76 @@ class WidgetUpdateWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
val views = RemoteViews(applicationContext.packageName, R.layout.widget_layout)
|
||||
|
||||
val sharedPref = applicationContext.getSharedPreferences("widget_prefs", Context.MODE_PRIVATE)
|
||||
val preferredCurrency = sharedPref.getString("preferredCurrency", "USD")
|
||||
val preferredCurrencyLocale = sharedPref.getString("preferredCurrencyLocale", "en-US")
|
||||
|
||||
val currentTime = SimpleDateFormat("hh:mm a", Locale.getDefault()).format(Date())
|
||||
val price = fetchPrice()
|
||||
val previousPrice = sharedPref.getString("previous_price", null)
|
||||
|
||||
// Log fetched data
|
||||
Log.d(TAG, "Fetch completed with price: $price at $currentTime. Previous price: $previousPrice")
|
||||
|
||||
// Update views
|
||||
val currencyFormat = NumberFormat.getCurrencyInstance(Locale.getDefault()).apply {
|
||||
maximumFractionDigits = 0
|
||||
}
|
||||
views.setTextViewText(R.id.price_value, currencyFormat.format(price.toDouble()))
|
||||
views.setTextViewText(R.id.last_updated_time, currentTime)
|
||||
views.setViewVisibility(R.id.last_updated_label, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.last_updated_time, View.VISIBLE)
|
||||
|
||||
if (previousPrice != null) {
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.VISIBLE)
|
||||
views.setTextViewText(R.id.previous_price, currencyFormat.format(previousPrice.toDouble()))
|
||||
if (price.toDouble() > previousPrice.toDouble()) {
|
||||
views.setImageViewResource(R.id.price_arrow, android.R.drawable.arrow_up_float)
|
||||
} else {
|
||||
views.setImageViewResource(R.id.price_arrow, android.R.drawable.arrow_down_float)
|
||||
}
|
||||
} else {
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.GONE)
|
||||
}
|
||||
// Show loading indicator
|
||||
views.setViewVisibility(R.id.loading_indicator, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.price_value, View.GONE)
|
||||
views.setViewVisibility(R.id.last_updated_label, View.GONE)
|
||||
views.setViewVisibility(R.id.last_updated_time, View.GONE)
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.GONE)
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetIds, views)
|
||||
|
||||
savePrice(sharedPref, price)
|
||||
val currentTime = SimpleDateFormat("hh:mm a", Locale.getDefault()).format(Date())
|
||||
|
||||
fetchPrice(preferredCurrency) { fetchedPrice, error ->
|
||||
if (error != null) {
|
||||
Log.e(TAG, "Error fetching price: $error")
|
||||
views.setViewVisibility(R.id.loading_indicator, View.GONE)
|
||||
views.setTextViewText(R.id.price_value, "Error fetching data")
|
||||
views.setViewVisibility(R.id.price_value, View.VISIBLE)
|
||||
} else {
|
||||
val previousPrice = sharedPref.getString("previous_price", null)
|
||||
val currentPrice = fetchedPrice?.toDouble()?.let { it.toInt() } // Remove cents
|
||||
|
||||
if (currentPrice == previousPrice?.toDouble()?.let { it.toInt() }) {
|
||||
views.setTextViewText(R.id.last_updated_time, currentTime)
|
||||
} else {
|
||||
Log.d(TAG, "Fetch completed with price: $fetchedPrice at $currentTime. Previous price: $previousPrice")
|
||||
val currencyFormat = NumberFormat.getCurrencyInstance(Locale.forLanguageTag(preferredCurrencyLocale!!)).apply {
|
||||
maximumFractionDigits = 0
|
||||
}
|
||||
views.setViewVisibility(R.id.loading_indicator, View.GONE)
|
||||
views.setTextViewText(R.id.price_value, currencyFormat.format(currentPrice))
|
||||
views.setTextViewText(R.id.last_updated_time, currentTime)
|
||||
views.setViewVisibility(R.id.price_value, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.last_updated_label, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.last_updated_time, View.VISIBLE)
|
||||
|
||||
if (previousPrice != null) {
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.VISIBLE)
|
||||
views.setTextViewText(R.id.previous_price, currencyFormat.format(previousPrice.toDouble().toInt()))
|
||||
if (currentPrice!! > previousPrice.toDouble().toInt()) {
|
||||
views.setImageViewResource(R.id.price_arrow, android.R.drawable.arrow_up_float)
|
||||
} else {
|
||||
views.setImageViewResource(R.id.price_arrow, android.R.drawable.arrow_down_float)
|
||||
}
|
||||
} else {
|
||||
views.setViewVisibility(R.id.price_arrow_container, View.GONE)
|
||||
}
|
||||
savePrice(sharedPref, fetchedPrice!!)
|
||||
}
|
||||
}
|
||||
appWidgetManager.updateAppWidget(appWidgetIds, views)
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
private fun fetchPrice(): String {
|
||||
val urlString = "https://api.kraken.com/0/public/Ticker?pair=XXBTZUSD"
|
||||
private fun fetchPrice(currency: String?, callback: (String?, String?) -> Unit) {
|
||||
val fiatUnitsJson = applicationContext.assets.open("fiatUnits.json").bufferedReader().use { it.readText() }
|
||||
val json = JSONObject(fiatUnitsJson)
|
||||
val currencyInfo = json.getJSONObject(currency ?: "USD")
|
||||
val source = currencyInfo.getString("source")
|
||||
val endPointKey = currencyInfo.getString("endPointKey")
|
||||
val urlString = buildURLString(source, endPointKey)
|
||||
|
||||
Log.d(TAG, "Fetching price from URL: $urlString")
|
||||
|
||||
val url = URL(urlString)
|
||||
val urlConnection = url.openConnection() as HttpURLConnection
|
||||
return try {
|
||||
try {
|
||||
val reader = InputStreamReader(urlConnection.inputStream)
|
||||
val jsonResponse = StringBuilder()
|
||||
val buffer = CharArray(1024)
|
||||
|
@ -94,13 +123,45 @@ class WidgetUpdateWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
while (reader.read(buffer).also { read = it } != -1) {
|
||||
jsonResponse.append(buffer, 0, read)
|
||||
}
|
||||
val json = JSONObject(jsonResponse.toString())
|
||||
json.getJSONObject("result").getJSONObject("XXBTZUSD").getJSONArray("c").getString(0)
|
||||
val responseJson = JSONObject(jsonResponse.toString())
|
||||
val price = parseJSONBasedOnSource(responseJson, source, endPointKey)
|
||||
callback(price, null)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error fetching price", e)
|
||||
callback(null, e.message)
|
||||
} finally {
|
||||
urlConnection.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildURLString(source: String, endPointKey: String): String {
|
||||
return when (source) {
|
||||
"Yadio" -> "https://api.yadio.io/json/$endPointKey"
|
||||
"YadioConvert" -> "https://api.yadio.io/convert/1/BTC/$endPointKey"
|
||||
"Exir" -> "https://api.exir.io/v1/ticker?symbol=btc-irt"
|
||||
"wazirx" -> "https://api.wazirx.com/api/v2/tickers/btcinr"
|
||||
"Bitstamp" -> "https://www.bitstamp.net/api/v2/ticker/btc${endPointKey.lowercase()}"
|
||||
"Coinbase" -> "https://api.coinbase.com/v2/prices/BTC-${endPointKey.uppercase()}/buy"
|
||||
"CoinGecko" -> "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=${endPointKey.lowercase()}"
|
||||
"BNR" -> "https://www.bnr.ro/nbrfxrates.xml"
|
||||
"Kraken" -> "https://api.kraken.com/0/public/Ticker?pair=XXBTZ${endPointKey.uppercase()}"
|
||||
else -> "https://api.coindesk.com/v1/bpi/currentprice/$endPointKey.json"
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseJSONBasedOnSource(json: JSONObject, source: String, endPointKey: String): String {
|
||||
return when (source) {
|
||||
"Kraken" -> json.getJSONObject("result").getJSONObject("XXBTZ${endPointKey.uppercase()}").getJSONArray("c").getString(0)
|
||||
"CoinGecko" -> json.getJSONObject("bitcoin").getString(endPointKey.lowercase())
|
||||
"Coinbase" -> json.getJSONObject("data").getString("amount")
|
||||
"Bitstamp" -> json.getString("last")
|
||||
"wazirx" -> json.getJSONObject("ticker").getString("buy")
|
||||
"Exir" -> json.getString("last")
|
||||
"Yadio", "YadioConvert" -> json.getJSONObject(endPointKey).getString("price")
|
||||
else -> throw IllegalArgumentException("Unsupported source: $source")
|
||||
}
|
||||
}
|
||||
|
||||
private fun savePrice(sharedPref: SharedPreferences, price: String) {
|
||||
sharedPref.edit().putString("previous_price", price).apply()
|
||||
}
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
android:background="@drawable/widget_background"
|
||||
android:gravity="end">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -21,7 +28,8 @@
|
|||
android:text="Last Updated"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginEnd="8dp"/>
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_updated_time"
|
||||
|
@ -31,7 +39,8 @@
|
|||
android:text=""
|
||||
android:textSize="12sp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="2dp"/>
|
||||
android:layout_marginTop="2dp"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -49,14 +58,16 @@
|
|||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
android:layout_marginBottom="8dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/price_arrow_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="end">
|
||||
android:gravity="end"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/price_arrow"
|
||||
|
@ -84,12 +95,5 @@
|
|||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -3,5 +3,5 @@
|
|||
<color name="background_color">#FFFFFF</color>
|
||||
<color name="widget_background">#FFFFFF</color>
|
||||
<color name="text_primary">#0C234F</color>
|
||||
<color name="text_secondary">#D3D3D3</color>
|
||||
<color name="text_secondary">#949494</color>
|
||||
</resources>
|
|
@ -5,8 +5,8 @@ buildscript {
|
|||
minSdkVersion = 24
|
||||
supportLibVersion = "28.0.0"
|
||||
buildToolsVersion = "34.0.0"
|
||||
compileSdkVersion = 34
|
||||
targetSdkVersion = 34
|
||||
compileSdkVersion = 33
|
||||
targetSdkVersion = 33
|
||||
googlePlayServicesVersion = "16.+"
|
||||
googlePlayServicesIidVersion = "16.0.1"
|
||||
firebaseVersion = "17.3.4"
|
||||
|
@ -15,18 +15,19 @@ buildscript {
|
|||
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
|
||||
ndkVersion = "23.1.7779620"
|
||||
kotlin_version = '1.9.25'
|
||||
kotlinVersion = '1.9.25'
|
||||
kotlinVersion = '1.9.23'
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:8.2.1")
|
||||
classpath("com.android.tools.build:gradle")
|
||||
classpath("com.bugsnag:bugsnag-android-gradle-plugin:5.+")
|
||||
classpath 'com.google.gms:google-services:4.4.2' // Google Services plugin
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,13 +37,13 @@ allprojects {
|
|||
url("$rootDir/../node_modules/detox/Detox-android")
|
||||
}
|
||||
|
||||
mavenCentral {
|
||||
// We don't want to fetch react-native from Maven Central as there are
|
||||
// older versions over there.
|
||||
content {
|
||||
excludeGroup "com.facebook.react"
|
||||
}
|
||||
}
|
||||
mavenCentral {
|
||||
// We don't want to fetch react-native from Maven Central as there are
|
||||
// older versions over there.
|
||||
content {
|
||||
excludeGroup "com.facebook.react"
|
||||
}
|
||||
}
|
||||
mavenLocal()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
|
@ -53,32 +54,17 @@ allprojects {
|
|||
url("$rootDir/../node_modules/jsc-android/dist")
|
||||
}
|
||||
google()
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
afterEvaluate { project ->
|
||||
if (project.plugins.hasPlugin("com.android.application") || project.plugins.hasPlugin("com.android.library")) {
|
||||
project.android {
|
||||
// Enable buildConfig feature
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
// Set namespace if not already set
|
||||
if (!namespace) {
|
||||
def manifestFile = android.sourceSets.main.manifest.srcFile
|
||||
if (manifestFile.exists()) {
|
||||
def manifestContent = new XmlParser().parse(manifestFile)
|
||||
def packageName = manifestContent.@package
|
||||
if (packageName) {
|
||||
namespace = packageName
|
||||
}
|
||||
}
|
||||
}
|
||||
afterEvaluate {project ->
|
||||
if (project.hasProperty("android")) {
|
||||
android {
|
||||
buildToolsVersion "34.0.0"
|
||||
compileSdkVersion 34
|
||||
defaultConfig {
|
||||
compileSdkVersion 33
|
||||
defaultConfig {
|
||||
minSdkVersion 24
|
||||
}
|
||||
}
|
||||
|
@ -90,5 +76,6 @@ subprojects {
|
|||
kotlinOptions.jvmTarget = sourceCompatibility
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue